为什么不使用shape标签
我想大家平常都用过shape标签来定义一个Drawable,来实现一些例如圆角、设置描边等一些需求。但是,最近发现一对一聊天app源码中res/drawable/下的shape标签文件越来越多,每当我们实现一些稍微不同的小需求时(例如圆角半径不同)就要新建一个shape标签的文件,这不仅很繁琐,还增加了内存、增加了apk的大小。
GradientDrawable:shape的动态实现
在我们使用shape标签定义的xml时,其实最终转化为了GradientDrawable。所以,一对一聊天app源码可以通过动态设置GradientDrawable来实现圆角、设置描边等功能需求。
动态实现圆角、修改背景色、设置描边Button
1、自定义GradientDrawable
有关GradientDrawable设置圆角、描边等API如下:
void | setColor(ColorStateList colorStateList) 将此drawable更改为使用单个颜色状态列表而不是渐变。 |
---|---|
void | setColor(int argb) 将此可绘制更改为使用单一颜色而不是渐变。 |
void | setColorFilter(ColorFilter colorFilter) 为绘图指定一个可选的颜色过滤器。 |
void | setColors(int[] colors) 设置用于绘制渐变的颜色。 |
void | setCornerRadii(float[] radii) 指定四个角的每一个的半径。 |
void | setCornerRadius(float radius) 指定渐变角的半径。 |
void | setDither(boolean dither) 此方法已弃用。该属性被忽略。 |
void | setGradientCenter(float x, float y) 设置渐变的像素中心位置。 |
void | setGradientRadius(float gradientRadius) 设置渐变的半径。 |
void | setGradientType(int gradient) 设置此drawable使用的渐变类型。 |
void | setOrientation(GradientDrawable.Orientation orientation) 设置此drawable中定义的渐变的方向。 |
void | setShape(int shape) 设置用于绘制渐变的形状的类型。 |
void | setSize(int width, int height) 设置由该drawable绘制的形状的大小。 |
void | setStroke(int width, ColorStateList colorStateList) 设置绘图的笔触宽度和颜色状态列表。 |
void | setStroke(int width, ColorStateList colorStateList, float dashWidth, float dashGap) 设置绘图的笔触宽度和颜色状态列表。 |
void | setStroke(int width, int color, float dashWidth, float dashGap) 设置绘图的笔触宽度和颜色。 |
void | setStroke(int width, int color) 设置绘图的笔触宽度和颜色。 |
void | setTintList(ColorStateList tint) 指定该drawable的色彩颜色作为颜色状态列表。 |
void | setTintMode(PorterDuff.Mode tintMode) 指定该drawable的色调混合模式。 |
void | setUseLevel(boolean useLevel) 设置这个drawable是否会遵守它的 level 属性。 |
更多用法请查看官方API:www.apiref.com/android-zh/…\
如果我们想更加方便的自定义配置圆角值等功能,需要继承GradientDrawable,关于自定义view的流程想必大家都熟悉这里不再详细说明,代码如下:
/**
* @author xiaoman
* res/drawable 中的shape文件动态设置
*/
public class RoundButtonDrawable extends GradientDrawable {
private int mStrokeWidth = 0;
/**
* 设置描边宽度和颜色
*/
void setStrokeData(int width, int color) {
mStrokeWidth = width;
setStroke(width, color);
}
void setStrokeColor(int color){
setStrokeData(mStrokeWidth, color);
}
static RoundButtonDrawable fromAttrSet(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundButton, defStyleAttr, 0);
int bgColor = typedArray.getColor(R.styleable.RoundButton_bgColor, ContextCompat.getColor(context,R.color.white));
int mRadius = typedArray.getDimensionPixelSize(R.styleable.RoundButton_radius, 0);
int mTopLeftRadius = typedArray.getDimensionPixelSize(R.styleable.RoundButton_topLeftRadius, 0);
int mTopRightRadius = typedArray.getDimensionPixelSize(R.styleable.RoundButton_topRightRadius, 0);
int mBottomLeftRadius = typedArray.getDimensionPixelSize(R.styleable.RoundButton_bottomLeftRadius, 0);
int mBottomRightRadius = typedArray.getDimensionPixelSize(R.styleable.RoundButton_bottomRightRadius, 0);
int strokeColor = typedArray.getColor(R.styleable.RoundButton_strokeColor,ContextCompat.getColor(context,R.color.white));
int strokeWidth = typedArray.getDimensionPixelSize(R.styleable.RoundButton_strokeWidth, 0);
typedArray.recycle();
RoundButtonDrawable roundButtonDrawable = new RoundButtonDrawable();
//设置背景颜色
roundButtonDrawable.setColor(bgColor);
//优先设置指定的圆角
if (mTopLeftRadius > 0 || mTopRightRadius > 0 || mBottomLeftRadius > 0 || mBottomRightRadius > 0) {
float[] radii = new float[]{
mTopLeftRadius, mTopLeftRadius,
mTopRightRadius, mTopRightRadius,
mBottomRightRadius, mBottomRightRadius,
mBottomLeftRadius, mBottomLeftRadius
};
roundButtonDrawable.setCornerRadii(radii);
} else {
roundButtonDrawable.setCornerRadius(mRadius);
}
//设置描边的宽度和颜色
roundButtonDrawable.setStrokeData(strokeWidth, strokeColor);
return roundButtonDrawable;
}
}
attr代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundButton">
<attr name="bgColor" format="color"/>
<attr name="radius" format="dimension"/>
<attr name="topLeftRadius" format="dimension"/>
<attr name="topRightRadius" format="dimension"/>
<attr name="bottomLeftRadius" format="dimension"/>
<attr name="bottomRightRadius" format="dimension"/>
<attr name="strokeColor" format="color"/>
<attr name="strokeWidth" format="dimension"/>
</declare-styleable>
<attr name="RoundButtonStyle" format="reference" />
</resources>
以上,就是一对一聊天app源码实现圆角和描边的内容了。
声明:本文由云豹科技转发自笑慢博客,如有侵权请联系作者删除