Android开发必备偷懒神器之比例控件(正方形、比例矩形)、点击效果(水波纹、滤镜)、Selector(CheckBox,RadioButton)、shape(圆角、ImageView圆角、画线、边
16lz
2021-01-26
GitHub_https://github.com/AnJiaoDe/AndroidNecessaryView
APKdemo_https://github.com/AnJiaoDe/AndroidNecessaryView/blob/master/app/build/outputs/apk/app-debug.apk
文章目录
- 1.控件点击效果(水波纹、图片滤镜)免去Selector和一个按钮2张图片的麻烦
- 2.比例控件(默认是正方形,还可以自定义比例,继承自水波纹控件,默认有点击效果)
- 3.各种shape背景(圆角,画线,虚线、渐变、边框、圆形、椭圆,继承自水波纹控件,默认有点击效果)
- 4.圆角ImageView(可加边框)
- 5.Selector(CheckBox,RadioButton,ImageView)设置button选中、未选中的drawable,设置bg选中未选中,设置src选中未选中
- 源码:
- 各位老铁有问题欢迎及时联系、指正、批评、撕逼
使用方法:将libray模块复制到项目中,或者直接在build.gradle中依赖:
allprojects {repositories {maven { url 'https://jitpack.io' }}}
dependencies { compile 'com.github.AnJiaoDe:AndroidNecessaryView:V1.0.1'}
注意:如果sync报错,是因为和com.android.tools.build:gradle 3.0有关,
可以改将compile改为implementation 或者api
注意:水波纹效果,5.0及以上才有效,需要设置点击事件监听器,才能看到
1.控件点击效果(水波纹、图片滤镜)免去Selector和一个按钮2张图片的麻烦
ClickImageView点击效果有滤镜和波纹2种,默认是滤镜,你可以设置为波纹效果
使用方法:
<?xml version="1.0" encoding="utf-8"?>
2.比例控件(默认是正方形,还可以自定义比例,继承自水波纹控件,默认有点击效果)
<?xml version="1.0" encoding="utf-8"?>
3.各种shape背景(圆角,画线,虚线、渐变、边框、圆形、椭圆,继承自水波纹控件,默认有点击效果)
<?xml version="1.0" encoding="utf-8"?>
4.圆角ImageView(可加边框)
引用自https://github.com/vinc3m1/RoundedImageView
<?xml version="1.0" encoding="utf-8"?>
5.Selector(CheckBox,RadioButton,ImageView)设置button选中、未选中的drawable,设置bg选中未选中,设置src选中未选中
<?xml version="1.0" encoding="utf-8"?>
源码:
public class ClickFrameLayout extends FrameLayout { public ClickFrameLayout(Context context) { this(context, null); } public ClickFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.ClickFrameLayout); //水波纹的颜色,默认是0x66000000,建议自定义水波纹颜色的时候,用argb,rgb都设置为0,a可随意,调整透明度为了水波纹看起来更美观 int colorRipple = arr.getColor(R.styleable.ClickFrameLayout_colorRipple, 0x66000000); boolean havaRipple = arr.getBoolean(R.styleable.ClickFrameLayout_haveRipple, true);//设置是否有水波纹点击效果,默认有 arr.recycle(); //5.0以上才有效, if (havaRipple&&android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { Drawable drawable = getBackground(); //当控件设置了点击监听器,并且控件点击有效,时,才能产生水波纹 RippleDrawable rippleDrawable = new RippleDrawable(ColorStateList.valueOf(colorRipple), drawable, null); setBackground(rippleDrawable); } }}
public class RectangleFrameLayout extends ClickFrameLayout { private float heightWidthRatio = 1; //高 / 宽(默认是高/宽),或者宽/高 比例 private boolean baseOnWidthOrHeight = true;//默认true,即默认基于宽 public RectangleFrameLayout(Context context) { this(context, null); } public RectangleFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.RectangleFrameLayout); heightWidthRatio = arr.getFloat(R.styleable.RectangleFrameLayout_heightWidthRatio, 1F); baseOnWidthOrHeight = arr.getBoolean(R.styleable.RectangleFrameLayout_baseOnWidthOrHeight, true); arr.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //默认基于宽,即高会和宽度一致,高由宽决定 if (baseOnWidthOrHeight) { int childWidthSize = getMeasuredWidth(); widthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY); heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) (childWidthSize * heightWidthRatio), MeasureSpec.EXACTLY); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); } else { //基于高,即宽度会和高度一致,宽度由高度决定 int childHeightSize = getMeasuredHeight(); heightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeightSize, MeasureSpec.EXACTLY); widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (childHeightSize * heightWidthRatio), MeasureSpec.EXACTLY); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); } }}
public class SelectorCheckBox extends AppCompatCheckBox { private int backgroundID, backgroundCheckedID, bg_color, bg_checked_color, textColorID, textColorCheckedID, buttonRes, buttonCheckedRes; private SelectorOnCheckedChangeListener selectorOnCheckedChangeListener; private boolean myListener = true; public SelectorCheckBox(Context context) { this(context, null); } public SelectorCheckBox(Context context, AttributeSet attrs) { super(context, attrs); TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.SelectorCheckBox); backgroundID = arr.getResourceId(R.styleable.SelectorCheckBox_backgroundUnChecked, -1);//未选中的背景资源 backgroundCheckedID = arr.getResourceId(R.styleable.SelectorCheckBox_backgroundChecked, -1);//选中的背景资源 if (backgroundID == -1) { bg_color = arr.getColor(R.styleable.SelectorCheckBox_backgroundUnChecked, 0x00000000);//未选中的背景颜色 } if (backgroundCheckedID == -1) { bg_checked_color = arr.getColor(R.styleable.SelectorCheckBox_backgroundChecked, 0x00000000);//选中的背景颜色 } buttonRes = arr.getResourceId(R.styleable.SelectorCheckBox_buttonUnChecked, -1);//未选中的按钮资源 buttonCheckedRes = arr.getResourceId(R.styleable.SelectorCheckBox_buttonChecked, -1);//选中的按钮资源 textColorID = arr.getColor(R.styleable.SelectorCheckBox_textColorUnChecked, getCurrentTextColor());//未选中的文字颜色 textColorCheckedID = arr.getColor(R.styleable.SelectorCheckBox_textColorChecked, getCurrentTextColor());//选中的文字颜色 arr.recycle(); if (isChecked()) { setResOnChecked(); } else { setResOnUnChecked(); } setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { setResOnChecked(); } else { setResOnUnChecked(); } if (selectorOnCheckedChangeListener != null) { selectorOnCheckedChangeListener.onCheckedChanged(buttonView, isChecked); } } }); } @Override public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { if (myListener) { super.setOnCheckedChangeListener(listener); myListener = false; } } //监听器使用这个方法 public void setSelectorOnCheckedChangeListener(SelectorOnCheckedChangeListener listener) { this.selectorOnCheckedChangeListener = listener; } public interface SelectorOnCheckedChangeListener extends OnCheckedChangeListener { @Override void onCheckedChanged(CompoundButton buttonView, boolean isChecked); } //设置选中时的背景,文字颜色等 private void setResOnChecked() { if (backgroundCheckedID != -1) { setBackgroundResource(backgroundCheckedID); } else { setBackgroundColor(bg_checked_color); } if (buttonCheckedRes != -1) { setButtonDrawable(buttonCheckedRes); } setTextColor(textColorCheckedID); } //设置未选中时的背景,文字颜色等 private void setResOnUnChecked() { if (backgroundID != -1) { setBackgroundResource(backgroundID); } else { setBackgroundColor(bg_color); } if (buttonRes != -1) { setButtonDrawable(buttonRes); } setTextColor(textColorID); }}
public class RecShapeFrameLayout extends FrameLayout { private float heightWidthRatio = 0; //高 / 宽(默认是高/宽),或者宽/高 比例 private boolean baseOnWidthOrHeight = true;//默认true,即默认基于宽 public RecShapeFrameLayout(Context context) { this(context, null); } public RecShapeFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.RecShapeFrameLayout); heightWidthRatio = arr.getFloat(R.styleable.RecShapeFrameLayout_heightWidthRatio, 0F); baseOnWidthOrHeight = arr.getBoolean(R.styleable.RecShapeFrameLayout_baseOnWidthOrHeight, true); //水波纹的颜色,默认是0x66000000,建议自定义水波纹颜色的时候,用argb,rgb都设置为0,a可随意,调整透明度为了水波纹看起来更美观 int colorRipple = arr.getColor(R.styleable.RecShapeFrameLayout_colorRipple, 0x66000000); boolean havaRipple = arr.getBoolean(R.styleable.RecShapeFrameLayout_haveRipple, true);//设置是否有水波纹点击效果,默认有 int radiusCorner = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_radiusCorner, 0);//圆角半径 int radiusTopLeft = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_radiusTopLeft, 0);//左上角圆角半径 int radiusTopRight = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_radiusTopRight, 0);//右上角圆角半径 int radiusBottomRight = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_radiusBottomRight, 0);//右下角圆角半径 int radiusBottomLeft = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_radiusBottomLeft, 0);//左下角圆角半径 int colorFill = arr.getColor(R.styleable.RecShapeFrameLayout_colorFill, 0x00000000);//填充色 //渐变相关 int radiusGradient = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_radiusGradient, 0);//渐变半径 int colorStart = arr.getColor(R.styleable.RecShapeFrameLayout_colorStart, 0x00000000);//渐变开始颜色 int colorCenter = arr.getColor(R.styleable.RecShapeFrameLayout_colorCenter, 0x00000000);///渐变中间颜色 int colorEnd = arr.getColor(R.styleable.RecShapeFrameLayout_colorEnd, 0x00000000);//渐变结束颜色 int orientationGradient = arr.getInt(R.styleable.RecShapeFrameLayout_orientationGradient, 6);//渐变方向,默认从左到右 int gradientType = arr.getInt(R.styleable.RecShapeFrameLayout_gradientType, 0);//渐变类型,默认线性渐变 float centerX = arr.getFloat(R.styleable.RecShapeFrameLayout_centerX, 0.5f);//渐变,相对于控件的中心点x坐标 float centerY = arr.getFloat(R.styleable.RecShapeFrameLayout_centerY, 0.5f);//渐变,相对于控件的中心点y坐标 int angle = arr.getInt(R.styleable.RecShapeFrameLayout_angle, 0);//渐变方向,默认从左到右 //stroke,描边相关 int strokeWidth = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_strokeWidth, 0);//描边粗细,宽度 int strokeColor = arr.getColor(R.styleable.RecShapeFrameLayout_strokeColor, 0x00000000);//描边颜色 int strokeDashWidth = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_strokeDashWidth, 0);//描边虚线宽度 int strokeDashGap = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_strokeDashGap, 0);//描边虚线间隔 //描边左边padding,用于控制左边描边的粗细和有无 int strokePaddingLeft = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_strokePaddingLeft, 0); //描边上边padding,用于控制上边描边的粗细和有无 int strokePaddingTop = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_strokePaddingTop, 0); //描边右边padding,用于控制右描边的粗细和有无 int strokePaddingRight = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_strokePaddingRight, 0); //描边下边padding,用于控制下描边的粗细和有无 int strokePaddingBottom = arr.getDimensionPixelSize(R.styleable.RecShapeFrameLayout_strokePaddingBottom, 0); //形状类型,默认矩形 int shapeType = arr.getInt(R.styleable.RecShapeFrameLayout_shapeType, 0); arr.recycle();// //设置了填充色或者设置了渐变色的开始和结束,或者设置了描边颜色,才会设置drawable if (colorFill == 0x00000000 && strokeColor == 0x00000000 && (colorStart == 0x00000000 || colorEnd == 0x00000000)) return; GradientDrawable gradientDrawable = new GradientDrawable();//创建背景drawable //形状类型 switch (shapeType) { case 0: gradientDrawable.setShape(GradientDrawable.RECTANGLE);//矩形 //,左上角开始,顺时针到左下角,1.左上角x方向弧度,2.左上角y方向弧度,3.右上角x方向弧度,4.右下角y方向弧度,以此类推 float[] cornerRadii = {radiusTopLeft, radiusTopLeft, radiusTopRight, radiusTopRight, radiusBottomRight, radiusBottomRight, radiusBottomLeft, radiusBottomLeft}; gradientDrawable.setCornerRadii(cornerRadii);//设置四个角的8个弧度半径 if (radiusCorner != 0) gradientDrawable.setCornerRadius(radiusCorner);//radiusCorner优先级比cornerRadii高 break; case 1: gradientDrawable.setShape(GradientDrawable.OVAL);//椭圆 break; case 2: gradientDrawable.setShape(GradientDrawable.LINE);//直线 break; case 3: gradientDrawable.setShape(GradientDrawable.RING);//圆环 break; } gradientDrawable.setColor(colorFill);//设置填充色 switch (gradientType) { case 0: gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);//线性渐变 //渐变方向,8个方向 switch (orientationGradient) { case 0: gradientDrawable.setOrientation(GradientDrawable.Orientation.TOP_BOTTOM);//从上到下 break; case 1: gradientDrawable.setOrientation(GradientDrawable.Orientation.TR_BL);//从右上到左下 break; case 2: gradientDrawable.setOrientation(GradientDrawable.Orientation.RIGHT_LEFT);//从右到左 break; case 3: gradientDrawable.setOrientation(GradientDrawable.Orientation.BR_TL);//从右下到左上 break; case 4: gradientDrawable.setOrientation(GradientDrawable.Orientation.BOTTOM_TOP);//从下到上 break; case 5: gradientDrawable.setOrientation(GradientDrawable.Orientation.BL_TR);//从左下到右上 break; case 6: gradientDrawable.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);//从左到右 break; case 7: gradientDrawable.setOrientation(GradientDrawable.Orientation.TL_BR);//从左上到右下 break; } break; case 1: gradientDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);//辐射渐变 gradientDrawable.setGradientRadius(radiusGradient);//设置渐变半径 gradientDrawable.setGradientCenter(centerX, centerY);//设置渐变相对于控件的中心点坐标,如(0.3,0.6) break; case 2: gradientDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);//扫描渐变 gradientDrawable.setGradientCenter(centerX, centerY);//设置渐变相对于控件的中心点坐标,如(0.3,0.6) break; } //设置渐变颜色 if (colorStart != 0x00000000 && colorEnd != 0x00000000) { int[] colors = {colorStart, colorCenter, colorEnd}; gradientDrawable.setColors(colors); } //描边 gradientDrawable.setStroke(strokeWidth, strokeColor, strokeDashWidth, strokeDashGap); Drawable[] layers = {gradientDrawable}; LayerDrawable layerDrawable = new LayerDrawable(layers); //设置描边方向,可控制每个方向的描边粗细和有无,不画线的方向,需要padding,strokeWidth的2倍 layerDrawable.setLayerInset(0, strokePaddingLeft, strokePaddingTop, strokePaddingRight, strokePaddingBottom); /* 设置drawable,大功告成 */ //5.0以上才有效, if (havaRipple&&android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { //当控件设置了点击监听器,并且控件点击有效,时,才能产生水波纹 RippleDrawable rippleDrawable = new RippleDrawable(ColorStateList.valueOf(colorRipple), layerDrawable, null); setBackground(rippleDrawable); return; } setBackground(layerDrawable); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (heightWidthRatio == 0) return; //默认基于宽,即高会和宽度一致,高由宽决定 if (baseOnWidthOrHeight) { int childWidthSize = getMeasuredWidth(); widthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY); heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) (childWidthSize * heightWidthRatio), MeasureSpec.EXACTLY); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); } else { //基于高,即宽度会和高度一致,宽度由高度决定 int childHeightSize = getMeasuredHeight(); heightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeightSize, MeasureSpec.EXACTLY); widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (childHeightSize * heightWidthRatio), MeasureSpec.EXACTLY); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); } }}
各位老铁有问题欢迎及时联系、指正、批评、撕逼
GitHub_https://github.com/AnJiaoDe
关注专题Android开发常用开源库_https://www.jianshu.com/c/3ff4b3951dc5
简书_https://www.jianshu.com/u/b8159d455c69
微信公众号
QQ群
更多相关文章
- Android多点触控实现图片自由缩放
- Android:MediaRecoder——录制音视频
- 常用控件及其属性(Button)
- Android(安卓)OpenGL ES从白痴到入门(二):App诞生
- android onMeasure 实现
- Android(安卓)第十一天重置版_新特性
- android设置默认程序
- Android中父子窗体调用类似模式窗体应用
- Android开发学习 之 五、基本界面控件