开源库FlycoRoundView解析
来源:互联网 发布:成都数据恢复 编辑:程序博客网 时间:2024/05/30 22:49
**FlycoRoundView
一个扩展原生控件支持圆角矩形框背景的库,可以减少相关shape资源文件使用
支持TextView,FrameLayout,LinearLayout,RelativeLayout,更多使用也可以自己扩展**
1.使用方法
实现以上的效果只需要如下,几个简单的自定义属性,
<com.flyco.roundview.RoundTextView android:id="@+id/rtv_3" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:ellipsize="end" android:gravity="center" android:paddingBottom="10dp" android:paddingLeft="18dp" android:paddingRight="18dp" android:paddingTop="10dp" android:singleLine="true" android:text="TextView Radius 10dpTextView Radius 10dp" android:textColor="#383838" rv:rv_backgroundColor="#F6CE59" rv:rv_cornerRadius="10dp" />
自定义xml属性的意思
<!-- 圆角矩形背景色 --> <attr name="rv_backgroundColor" format="color"/> <!-- 圆角矩形背景色press --> <attr name="rv_backgroundPressColor" format="color"/> <!-- 圆角弧度,单位dp--> <attr name="rv_cornerRadius" format="dimension"/> <!-- 圆角弧度,单位dp--> <attr name="rv_strokeWidth" format="dimension"/> <!-- 圆角边框颜色--> <attr name="rv_strokeColor" format="color"/> <!-- 圆角边框颜色press --> <attr name="rv_strokePressColor" format="color"/> <!-- 文字颜色press--> <attr name="rv_textPressColor" format="color"/> <!-- 圆角弧度是高度一半--> <attr name="rv_isRadiusHalfHeight" format="boolean"/> <!-- 圆角矩形宽高相等,取较宽高中大值--> <attr name="rv_isWidthHeightEqual" format="boolean"/> <!-- 圆角弧度,单位dp,TopLeft--> <attr name="rv_cornerRadius_TL" format="dimension"/> <!-- 圆角弧度,单位dp,TopRight--> <attr name="rv_cornerRadius_TR" format="dimension"/> <!-- 圆角弧度,单位dp,BottomLeft--> <attr name="rv_cornerRadius_BL" format="dimension"/> <!-- 圆角弧度,单位dp,BottomRight--> <attr name="rv_cornerRadius_BR" format="dimension"/> <!-- 是否有Ripple效果,api21+有效--> <attr name="rv_isRippleEnable" format="boolean"/>
代码解析
通过观察源码,主要有如下几个类
- RoundFrameLayout
- RoundLinearLayout
- RoundRelativeLayout
- RoundTextView
- RoundViewDelegate
其中所有的自定义View的代码大致全都是这样
public RoundRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); //主要逻辑在这里面初始化 delegate = new RoundViewDelegate(this, context, attrs); } /** use delegate to set attr */ public RoundViewDelegate getDelegate() { return delegate; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //判断是否设置为是宽高相同 if (delegate.isWidthHeightEqual() && getWidth() > 0 && getHeight() > 0) { int max = Math.max(getWidth(), getHeight()); int measureSpec = MeasureSpec.makeMeasureSpec(max, MeasureSpec.EXACTLY); super.onMeasure(measureSpec, measureSpec); return; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); //判断是否圆角取高的一半 if (delegate.isRadiusHalfHeight()) { delegate.setCornerRadius(getHeight() / 2); }else { delegate.setBgSelector(); } }
主要代码集中在RoundViewDelegate里面,进去看看
取出xml中的属性 ,如果对自定义xml属性不熟悉–>戳这里Android 深入理解Android中的自定义属性
//取出xml中的属性 private void obtainAttributes(Context context, AttributeSet attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RoundTextView); backgroundColor = ta.getColor(R.styleable.RoundTextView_rv_backgroundColor, Color.TRANSPARENT); //~~~省略代码 isRippleEnable = ta.getBoolean(R.styleable.RoundTextView_rv_isRippleEnable, true); ta.recycle(); }
在各个自定义View中看到,在onLayout中会调用setBgSelector()方法,进去看看
public void setBgSelector() { //StateListDrawable类对应<selector>这个xml标签 StateListDrawable bg = new StateListDrawable(); //如果是5.0以上的系统,可以设置水波纹的效果 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && isRippleEnable) { setDrawable(gd_background, backgroundColor, strokeColor); //对应<ripple>标签 RippleDrawable rippleDrawable = new RippleDrawable( getPressedColorSelector(backgroundColor, backgroundPressColor), gd_background, null); //设置为View背景 view.setBackground(rippleDrawable); } else { //设置四个角的圆角弧度,背景颜色 setDrawable(gd_background, backgroundColor, strokeColor); //前面加个‘-’,相当于xml中的 state_pressed属性为false的时候, bg.addState(new int[]{-android.R.attr.state_pressed}, gd_background); if (backgroundPressColor != Integer.MAX_VALUE || strokePressColor != Integer.MAX_VALUE) { //设置按下去的背景色 setDrawable(gd_background_press, backgroundPressColor == Integer.MAX_VALUE ? backgroundColor : backgroundPressColor, strokePressColor == Integer.MAX_VALUE ? strokeColor : strokePressColor); bg.addState(new int[]{android.R.attr.state_pressed}, gd_background_press); } //设置背景 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {//16 view.setBackground(bg); } else { //noinspection deprecation view.setBackgroundDrawable(bg); } } //如果是TextView,设置字体的颜色,按下去的颜色 if (view instanceof TextView) { if (textPressColor != Integer.MAX_VALUE) { ColorStateList textColors = ((TextView) view).getTextColors();// Log.d("AAA", textColors.getColorForState(new int[]{-android.R.attr.state_pressed}, -1) + ""); ColorStateList colorStateList = new ColorStateList( new int[][]{new int[]{-android.R.attr.state_pressed}, new int[]{android.R.attr.state_pressed}}, new int[]{textColors.getDefaultColor(), textPressColor}); ((TextView) view).setTextColor(colorStateList); } } }
设置背景的方法全都在这里了~比较简单,基本就是把以前只能用xml写死的selector等等标签,用java代码变灵活了!
private void setDrawable(GradientDrawable gd, int color, int strokeColor) { //设置Drawable的背景色 gd.setColor(color); //四个角设置圆角 if (cornerRadius_TL > 0 || cornerRadius_TR > 0 || cornerRadius_BR > 0 || cornerRadius_BL > 0) { /**The corners are ordered top-left, top-right, bottom-right, bottom-left*/ radiusArr[0] = cornerRadius_TL; radiusArr[1] = cornerRadius_TL; radiusArr[2] = cornerRadius_TR; radiusArr[3] = cornerRadius_TR; radiusArr[4] = cornerRadius_BR; radiusArr[5] = cornerRadius_BR; radiusArr[6] = cornerRadius_BL; radiusArr[7] = cornerRadius_BL; gd.setCornerRadii(radiusArr); } else { //全都设置成cornerRadius gd.setCornerRadius(cornerRadius); } //设置边框 gd.setStroke(strokeWidth, strokeColor); }
以下是Drawable Xml对应的的class类
GradientDrawable
<shape> 对应 GradientDrawable//设置背景颜色setColor(@ColorInt int argb)//设置各个角的弧度setCornerRadii(float[] radii)//左上角 右上角 右下角 左下角 这里数组长度必须是8位 如下gradientDrawable1.setCornerRadii(new float[]{0,0,8,8,16,16,32,32});//设置四个角的弧度setCornerRadius(float radius)//设置边框 宽度,和颜色setStroke(int width, @ColorInt int color)
StateListDrawable
<selector> 对应 StateListDrawable类主要方法有以下//对应xml的属性,当前状态下的显示背景addState(new int[]{-android.R.attr.state_pressed}, gd_background);这里可以同时设置多个状态比如 stateListDrawable.addState( new int[]{-android.R.attr.state_pressed, -android.R.attr.state_checked, -android.R.attr.state_selected,gradientDrawable1);
主要用到的就是这两个类了~~
0 0
- 开源库FlycoRoundView解析
- FlycoRoundView
- FlycoRoundView 自定义TextView
- 开源库guillotine使用解析
- H264解析开源库H264Bitstream
- 解析
- 解析
- 解析
- 解析
- 解析
- 解析
- 解析
- 解析
- 解析
- 解析[ ]
- 解析
- iOS开源库解析之ASIHTTPRequest
- 开源库Fab-Transformation简单使用解析
- ViewPagerIndicator的使用
- App Manifest详解
- java基础15集合List
- 最大连续两段不相交字段和(poj2594,poj2479)
- 算法学习--贪心算法
- 开源库FlycoRoundView解析
- 欢迎使用CSDN-markdown编辑器
- nefuoj-1041:字符串变形记
- Asp.Net alert弹出提示信息的几种方法总结
- ElasticSearch初步学习,创建索引(入门一)
- CodeVS3044矩形面积求并
- Android Layout 之 RelativeLayout
- Java正则表达式特殊字符
- 关于Activity的生命周期和启动模式(附Demo)