在开发中,经常遇到一种需求,对文本设置边框背景。常用的方式是通过xml中使用shape来实现。但是该方法面临的问题是每种颜色,每个不同弧度的shape文件都需要一一编写。
现在有如下需求,根据后台配置的颜色来动态设置边框颜色。这个时候可以使用GradientDrawable来直接修改属性或动态创建一个。
操作背景shape
针对设置了background属性的view,注意必须是shape的背景。可以通过getBackground获取背景并转化为GradientDrawable,进而设置背景边框颜色。当然也可以在GradientDrawable能力范围内设置其它属性。
GradientDrawable drawable = (GradientDrawable) view.getBackground().mutate();
drawable.setStroke(1, color);
但是注意上面使用了getBackground().mutate(),原因可参考Drawable的mutate方法——多ImageView.setAlpha失效问题解决。
可以使用drawable.getConstantState().newDrawable()新建一个GradientDrawable,共享其CommonState(颜色等),以便于不同尺寸的宿主view设置背景图片。 不要将同一drawable对象设置给多个view。
动态创建
即用代码动态创建一个GradientDrawable后,设置为view的背景。
GradientDrawable drawable = new GradientDrawable();
drawable.setCornerRadius(10);
drawable.setStroke(2,Color.BLUE);
tv.setBackgroundDrawable(drawable);
shape到GradientDrawable的创建
根据Resources.getDrawable方法的调用流程,调用ResourcesImpl.loadDrawable方法,调用Drawable.createFromXmlForDensity方法,调用DrawableInflater.inflateFromXmlForDensity方法,下面是创建时的关键代码片段:
这也说明了上面第一种直接操作背景GradientDrawable的方法只适用于shape背景。
参考文档:
神奇的Drawable文件夹---背景图篇