Android Shape Drawable 改变属性
Posted
技术标签:
【中文标题】Android Shape Drawable 改变属性【英文标题】:Android Shape Drawable changing attributes 【发布时间】:2015-03-13 16:55:37 【问题描述】:我有几个形状可绘制资源,我想用作按钮的背景,它们是相似的,除了渐变开始和结束颜色以及笔触颜色。 问题是我不想为这个可绘制对象创建几个类似的 XML 文件。
我认为我可以像使用标签的样式一样继承可绘制的形状,但这是不可能的。
我找到了这个Defining XML Parent Style of Gradient / Shape / Corners,但我不明白它是如何工作的。他是如何改变属性值的?
Using parents for drawable resources 我发现我可以通过 layer-list 更改背景的外观,这将在另一个之上绘制可绘制图层。但是如何使用 layer-list 来处理渐变和描边颜色呢?
我发现我可以在运行时更改按钮背景的外观,但可能有更简单的方法可以做到这一点?
【问题讨论】:
实现ShapeDrawable.ShaderFactory.resize()
创建一个新的LinearGradient
对象,它是Shader
的子类,然后返回该对象。然后调用ShapeDrawable.setShader()
将ShaderFactory
的实现传递给它。无法更改渐变的属性,您必须重新绘制颜色才能更新它们。抱歉,我没有笔记本电脑
感谢您的建议,我会试试这个并回复。当你有笔记本电脑时,你能发布一个小例子吗?这对我很有帮助,我将不胜感激
您确定这对 Eclipce 有效吗?
是的,绝对是,但与此同时,您应该检查文档中的 ShapeDrawable.setShader()
和 ShaderFactory
和 Shader
,非常不言自明。哈哈,不管是哪个IDE,而且Eclipse已经是历史了,你应该切换到android Studio,它更聪明,有更有效的方式来添加和管理你的依赖等等。 Google 也将停止支持 Eclipse,AS 是下一代
另外,查看Shader
的子类,你会需要它们
【参考方案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
用作新背景,以及不带 ()
的方法名称,例如要在其上运行的 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);
按钮的初始背景
<?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>
【讨论】:
我昨天有事,没时间打开堆栈查看您的回答,对此感到抱歉 附注我了解 RTTI 机制,特别感谢屏幕截图和 cmets 大声笑,别抱歉,记住,以这种方式使用反射调用新 API 不会使您的应用在旧版本访问它时崩溃,但速度很慢,请查看此以了解其他技术android-developers.blogspot.com/2009/04/… 感谢文档(关于兼容性)我可以稍后向您展示我的按钮,通过这种方式制作吗?然后是我的项目? 我可以在 facebook 上找到你吗,或者你能给我你的电子邮件吗?因为我目前不能在那里发布图片(因为我的费率)【参考方案2】:哈哈,我没有使用反射,而是根据当前版本使用此代码来设置专有背景
int sdk = android.os.Built.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN)
setBackgroundDrawable();
else
setBackground();
【讨论】:
以上是关于Android Shape Drawable 改变属性的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的Android Studio里新建的drawable的XML文件里没找不到shape这个选项.