我有几个形状可绘制的资源,我想用作按钮的背景,它们是相似的,除了渐变开始和结束颜色和笔触颜色。 问题是我不想为这个drawables创建几个类似的XML文件。
我认为我可以像使用标签的样式一样继承shape drawable,但这是不可能的。
我发现了这个Defining XML Parent Style of Gradient / Shape / Corners,但我不明白它是如何工作的。他如何改变属性值?
有Using parents for drawable resources我发现我可以通过图层列表更改背景的外观,这将在另一个上面绘制可绘制图层。但是如何使用layer-list操作渐变和描边颜色?
我发现我可以在运行时更改按钮背景的外观,但可能有一种更简单的方法可以做到这一点?
答案 0 :(得分:1)
我提出的初步建议是不可行的。我认为<shape>
会返回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
用作新背景,以及没有()
的方法的名称,如{{ 1}}在旧版本上运行。反思很慢。谨慎使用它。
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);
}
}
按钮的初始背景
/**
* I am extending the GradientDrawable just for fun, and also
* because I want to set the shader property for this drawable,
* you could, however, use the GradientDrawable directly.
*/
public class Gradient extends GradientDrawable {
private Paint paint;
private LinearGradient gradient;
public Gradient()
{
super();
// check the docs for LinearGradient for these parameters
gradient = new LinearGradient(0,0, 100, 100, Color.BLUE, Color.GREEN, Shader.TileMode.REPEAT);
paint = new Paint();
paint.setShader(gradient);
}
public Gradient(GradientDrawable.Orientation orientation, int[] colors)
{
super(orientation, colors);
gradient = new LinearGradient(0,0, 100, 100, Color.BLUE, Color.GREEN, Shader.TileMode.REPEAT);
paint = new Paint();
paint.setShader(gradient);
}
@Override
public void draw(Canvas canvas)
{
canvas.drawPaint(paint);
}
}
答案 1 :(得分:0)
哈,而不是使用思考我根据当前版本使用此代码来设置专用背景
int sdk = android.os.Built.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
setBackgroundDrawable();
} else {
setBackground();
}