gpt4 book ai didi

android-layout - 在 Android 代码中创建环形

转载 作者:行者123 更新时间:2023-11-29 14:18:10 25 4
gpt4 key购买 nike

我有以下形状的 XML:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:a="http://schemas.android.com/apk/res/android"
a:shape="ring"
a:innerRadiusRatio="3"
a:thicknessRatio="8"
a:useLevel="false">

<!-- some other stuff goes here -->

</gradient>
</shape>

我想改用代码来创建这个形状,因为有些事情需要在我做之前即时计算,所以静态预定义布局不会削减它。

我是 Android 的新手,不太明白 XML 如何转换为代码,而且没有从 Shape 继承的 RingShape 类。

除了仅回答这个问题之外,如果某处有详细说明 XML 和 Java 代码之间的关系以及如何处理 XML 以便最终显示在屏幕上的指南,我也希望能提供一个链接。谢谢。

最佳答案

Reuben 已经指出了大部分最有用的观察结果,所以我将只关注故事的实现方面。有多种使用反射的方法可能会为您提供您正在寻找的东西。

第一个是(ab)使用带有 GradientState 引用的私有(private) GradientDrawable 构造函数。不幸的是,后者是具有包可见性的最终子类,因此您无法轻松访问它。为了使用它,您需要进一步深入使用反射或将其功能模仿到您自己的代码中。

第二种方法是使用反射获取私有(private)成员变量mGradientState,幸好它有一个getter,形式为getConstantState()。这将为您提供 ConstantState,它在运行时实际上是一个 GradientState,因此我们可以使用反射来访问其成员并在运行时更改它们。

为了支持上述陈述,这里有一个从代码创建环形可绘制对象的基本实现:

RingDrawable.java

public class RingDrawable extends GradientDrawable {

private Class<?> mGradientState;

public RingDrawable() {
this(Orientation.TOP_BOTTOM, null);
}

public RingDrawable(int innerRadius, int thickness, float innerRadiusRatio, float thicknessRatio) {
this(Orientation.TOP_BOTTOM, null, innerRadius, thickness, innerRadiusRatio, thicknessRatio);
}

public RingDrawable(GradientDrawable.Orientation orientation, int[] colors) {
super(orientation, colors);
setShape(RING);
}

public RingDrawable(GradientDrawable.Orientation orientation, int[] colors, int innerRadius, int thickness, float innerRadiusRatio, float thicknessRatio) {
this(orientation, colors);
try {
setInnerRadius(innerRadius);
setThickness(thickness);
setInnerRadiusRatio(innerRadiusRatio);
setThicknessRatio(thicknessRatio);
} catch (Exception e) {
// fail silently - change to your own liking
e.printStackTrace();
}
}

public void setInnerRadius(int radius) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
if (mGradientState == null) mGradientState = resolveGradientState();
Field innerRadius = resolveField(mGradientState, "mInnerRadius");
innerRadius.setInt(getConstantState(), radius);
}

public void setThickness(int thicknessValue) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
if (mGradientState == null) mGradientState = resolveGradientState();
Field thickness = resolveField(mGradientState, "mThickness");
thickness.setInt(getConstantState(), thicknessValue);
}

public void setInnerRadiusRatio(float ratio) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
if (mGradientState == null) mGradientState = resolveGradientState();
Field innerRadiusRatio = resolveField(mGradientState, "mInnerRadiusRatio");
innerRadiusRatio.setFloat(getConstantState(), ratio);
}

public void setThicknessRatio(float ratio) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
if (mGradientState == null) mGradientState = resolveGradientState();
Field thicknessRatio = resolveField(mGradientState, "mThicknessRatio");
thicknessRatio.setFloat(getConstantState(), ratio);
}

private Class<?> resolveGradientState() {
Class<?>[] classes = GradientDrawable.class.getDeclaredClasses();
for (Class<?> singleClass : classes) {
if (singleClass.getSimpleName().equals("GradientState")) return singleClass;
}
throw new RuntimeException("GradientState could not be found in current GradientDrawable implementation");
}

private Field resolveField(Class<?> source, String fieldName) throws SecurityException, NoSuchFieldException {
Field field = source.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
}

}

可以按如下方式使用 Above 从代码创建 RingDrawable 并将其显示在标准 ImageView 中。

ImageView target = (ImageView) findViewById(R.id.imageview);
RingDrawable ring = new RingDrawable(10, 20, 0, 0);
ring.setColor(Color.BLUE);
target.setImageDrawable(ring);

这将在 ImageView 中显示一个简单的不透明蓝色环(内半径为 10 个单位,厚度为 20 个单位)。您需要确保不要将 ImageView 的宽度和高度设置为 wrap_content,除非您将 ring.setSize(width, height) 添加到上面的代码中以便它出现。

希望这能以任何方式帮助您。

关于android-layout - 在 Android 代码中创建环形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9346112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com