GradientDrawable的使用,和简单源码分析
Posted 夜尽天明89
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GradientDrawable的使用,和简单源码分析相关的知识,希望对你有一定的参考价值。
gradient:英 [ˈgreidjənt] 美 [ˈgredɪənt] 倾斜度,坡度,变化率
从字面意思理解,是一个可以变化颜色、有渐变效果的Drawable
GradientDrawable extends Drawable
来个效果图和对应的代码。并不复杂
对应代码(布局我就不写了,没有任何特别的)
//圆角矩形。TextView
rounded_rectangle.apply
var gradientDrawable: GradientDrawable = GradientDrawable()
Log.e("000 = call back ","$gradientDrawable.callback")
gradientDrawable.setColor(Color.GREEN)
Log.e("111 = call back ","$gradientDrawable.callback")
gradientDrawable.cornerRadius = dp2Px(20f)
Log.e("222 = call back ","$gradientDrawable.callback")
background = gradientDrawable
Log.e("333 = call back ","$gradientDrawable.callback")
//圆角矩形,设置4个角不同的度数。TextView
rounded_rectangle_radius.apply
var gradientDrawable: GradientDrawable = GradientDrawable()
gradientDrawable.setColor(Color.GREEN)
gradientDrawable.setCornerRadii(
floatArrayOf(
dp2Px(10f),
dp2Px(10f),
dp2Px(15f),
dp2Px(15f),
dp2Px(20f),
dp2Px(20f),
dp2Px(25f),
dp2Px(25f)
)
)
background = gradientDrawable
//圆角矩形,带边线。TextView
rounded_rectangle_stroke.apply
var gradientDrawable: GradientDrawable = GradientDrawable()
gradientDrawable.setColor(Color.GREEN)
gradientDrawable.cornerRadius = dp2Px(20f)
gradientDrawable.setStroke(dp2Px(2f).toInt(), Color.RED)
background = gradientDrawable
//水平线。view
h_line.apply
var gradientDrawable: GradientDrawable = GradientDrawable()
gradientDrawable.setShape(GradientDrawable.LINE);
gradientDrawable.setStroke(2, Color.RED);
background = gradientDrawable
//水平虚线。view
h_xu_line.apply
var gradientDrawable: GradientDrawable = GradientDrawable()
gradientDrawable.setShape(GradientDrawable.LINE);
gradientDrawable.setStroke(2, Color.RED, 10f, 30f);
background = gradientDrawable
//圆形控件。TextView
circle_view.apply
var gradientDrawable: GradientDrawable = GradientDrawable()
gradientDrawable.setColor(Color.GREEN);
gradientDrawable.setShape(GradientDrawable.OVAL);
background = gradientDrawable
//圆形控件,渐变背景。TextView
circle_view_2.apply
var gradientDrawable: GradientDrawable = GradientDrawable()
gradientDrawable.setShape(GradientDrawable.OVAL)
//设置描边
gradientDrawable.setStroke(dp2Px(2f).toInt(), Color.RED)
//设置线性渐变,除此之外还有:GradientDrawable.SWEEP_GRADIENT(扫描式渐变),GradientDrawable.RADIAL_GRADIENT(圆形渐变)
gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT)
gradientDrawable.setOrientation(GradientDrawable.Orientation.RIGHT_LEFT) //设置渐变方向
gradientDrawable.setColors(
intArrayOf(
Color.RED,
Color.GREEN,
Color.BLUE
)
) //增加渐变效果需要使用setColors方法来设置颜色(中间可以增加多个颜色值)
// gradientDrawable.alpha = 70 //设置透明度
background = gradientDrawable
接下来,简单分析下这个的源码。
var gradientDrawable: GradientDrawable = GradientDrawable()
gradientDrawable.XXX(...)
任何一个方法进去,都会调用
invalidateSelf()
去看 invalidateSelf ,会进入Drawable
public void invalidateSelf()
final Callback callback = getCallback();
if (callback != null)
callback.invalidateDrawable(this);
这个callback,是Drawable下的,全部方法如下
public interface Callback
void invalidateDrawable(@NonNull Drawable who);
void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when);
void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what);
也就是说,在使用 GradientDrawable 的时候,每次设置属性,都会进行2步操作:1、获取回调接口;2、如果回调不为空,就调用 invalidateDrawable 去绘制。
什么时候 回调 不为空呢?也就是,什么时候,会去绘制呢?我上面代码里加了Log,看下日志
E/000 = call back: null
E/111 = call back: null
E/222 = call back: null
E/333 = call back: androidx.appcompat.widget.AppCompatTextViewee92a86 V.ED..... ......I. 0,0-0,0 #7f070082 app:id/rounded_rectangle
看来,是TextView设置了 background 后,才进行了背景的绘制。
去看下 TextView 的 setBackground
public void setBackground(Drawable background)
//noinspection deprecation
setBackgroundDrawable(background);
public void setBackgroundDrawable(Drawable background)
......
if (background != null)
......
// Set callback last, since the view may still be initializing.
background.setCallback(this);
......
......
总结下:GradientDrawable 设置各种属性的时候,因为callback 为空,不会进行绘制(不会造成浪费)。在最后设置 setBackground 时,传入了 background ,且设置了 callback ,在后续代码中,触发了绘制
以上是关于GradientDrawable的使用,和简单源码分析的主要内容,如果未能解决你的问题,请参考以下文章