Android形状可绘制更改属性

Android形状可绘制更改属性,android,shapedrawable,Android,Shapedrawable,我有几个形状可绘制的资源,我想作为按钮的背面使用,他们是相似的,除了梯度开始和结束颜色和笔划颜色。 问题是我不想为这个drawables创建几个类似的XML文件 我认为我可以像使用标记的样式一样继承可绘制的形状,但这是不可能的 我找到了这个,但我不明白它是怎么工作的。他如何改变属性值 在那个里,我发现我可以通过图层列表来改变背景的外观,这样可以一层一层地绘制可绘制的图层。但是如何使用图层列表处理渐变和笔划颜色呢 我发现我可以在运行时更改按钮背景的外观,但可能有更简单的方法可以做到这一点?我最初的

我有几个形状可绘制的资源,我想作为按钮的背面使用,他们是相似的,除了梯度开始和结束颜色和笔划颜色。 问题是我不想为这个drawables创建几个类似的XML文件

我认为我可以像使用标记的样式一样继承可绘制的形状,但这是不可能的

我找到了这个,但我不明白它是怎么工作的。他如何改变属性值

在那个里,我发现我可以通过图层列表来改变背景的外观,这样可以一层一层地绘制可绘制的图层。但是如何使用图层列表处理渐变和笔划颜色呢


我发现我可以在运行时更改按钮背景的外观,但可能有更简单的方法可以做到这一点?

我最初的建议是不可行的。我以为
会返回一个
ShapeDrawable
,但我错了,下面我将如何修改渐变

单击按钮之前

单击按钮后,其背景会发生变化。

这是主要的活动

public class MainActivity extends Activity {

    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button)findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                try
                {
                    // you can use the GradientDrawable directly, check the docs for details,
                    // I extended GradientDrawable just to make myself look like a badass :)

                    MyReflection.invokeMethod(button, new Gradient(), "setBackground");
                } 

                catch (NoSuchMethodException e)
                {
                    e.printStackTrace();
                } 

                catch (InvocationTargetException e)
                {
                    e.printStackTrace();
                } 

                catch (IllegalAccessException e)
                {
                    e.printStackTrace();
                }
            }
        });

     }
}
获取一个新方法的实用方法,该方法带有一个要调用该方法的对象,
Drawable
用作新的背景,以及不带
()
的方法的名称,例如
setBackground
以在旧版本上运行。反射很慢。少用它

/*
* We want to use reflection because the View.setBackground() method
* is only available on API level 16 and up.
* If you don't understand this, you can follow the tutorial provided by
* Oracle, just search for it on Google with the keyword "reflection tutorial"
*/

public class MyReflection {

    public static void invokeMethod(Object receiverObject, Drawable background, String methodName)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
    {
        Class<?> clazz = View.class;

        Method method = clazz.getMethod(methodName, Drawable.class);

        // Allowing non-public access call to this method.
        method.setAccessible(true);
        method.invoke(receiverObject, background);
    }
}
按钮的初始背景

<?xml version="1.0" encoding="utf-8"?>
<!-- The initial shape with just a solid yellow color -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid
        android:color="#ff0"/>

</shape>

hah,我没有使用反射,而是根据当前版本使用此代码来设置专用背景

int sdk = android.os.Built.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
    setBackgroundDrawable();
} else {
    setBackground();
}
intsdk=android.os.build.VERSION.sdk\u int;
if(sdk
实现
ShapeDrawable.ShaderFactory.resize()
创建一个新的
LinearGradient
对象,该对象是
着色器的子类,然后返回该对象。然后调用
ShapeDrawable.setShader()
ShaderFactory的实现传递给它。没有办法更改渐变的属性,您必须重新绘制颜色以更新它们。对不起,我没有笔记本电脑谢谢你的建议,我会试试这个然后回复。当你有笔记本电脑时,你能举个小例子吗?这将对我非常有帮助,我将不胜感激。你确定这对Eclipce正确吗?是的,绝对正确,但同时,你应该检查文档中的
ShapeDrawable.setShader()
,以及
ShaderFactory
Shader
,这是不言自明的。哈哈,不管是哪一个IDE,而且Eclipse已经成为历史,你应该切换到Android Studio,它更智能,有一种更有效的方式来添加和管理你的依赖关系等等。此外,谷歌将停止支持Eclipse,因为这是下一代。因此,请查看
着色器的子类,您将需要它们。我昨天有一些业务,我没有时间打开堆栈查看您的答案,对此p.s.深表歉意。我了解RTTI机制,特别感谢您提供的屏幕截图和评论。L,不要抱歉,记住,使用反射以这种方式调用新API不会使您的应用程序在旧版本访问时崩溃,但速度较慢,请检查此项以了解其他技术。感谢doc(关于兼容性)我可以稍后向您展示我的按钮吗,这样做的?我可以在facebook上找到你吗?或者你可以给我你的电子邮件吗?因为我目前无法在那里发布图像(因为我的速率)
int sdk = android.os.Built.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
    setBackgroundDrawable();
} else {
    setBackground();
}