国产操作系统生态圈推动信息安全与技术自主发展的新机遇
802
2022-11-17
自定义View
今天跟着简书学习自定义view的详解:传送门
1、自定义的分类
自定义View一共分两大类:
2、具体使用场景
3、使用注意点
下面是自定义View会出现的一些坑:
3.1、支持特殊属性
支持wrap_content就是在onMeasure中去根据LayoutParams去设置指定的宽高。下面是为什么要支持wrap_content的原因。为什么自定义view的wrap_content无效支持padding & margin如果不支持,那么padding和margin(ViewGroup情况)的属性将失效(1)对于继承View的控件,padding是在onDraw()中处理(2)对于继承ViewGroup的控件,padding会直接影响layout和draw的过程。
3.2、多线程应该使用post方式 View内部本身提供了post系列的方法,安全可以替代Handler的作用。使用起来更加方便。
3.3、避免内存泄漏 当View退出或者不可见时,应该及时关闭view中的动画以及耗时操作。否则会造成内存泄漏。
3.4、处理好滑动冲突 如果View中含有滑动嵌套情况时,应该处理好滑动冲突。
4、实例
4.1继承View 我们将实现一个实心圆,然后为其提供颜色等属性,并且使其支持wrap_content和padding
4.2、实现过程 步骤1:我们创建一个CircleView.java:
步骤2:在xml中加入这个view
效果如下:
接着手动支持wrap_content和padding,以及为自定义view设置属性。
(1)支持wrap_content
(2)padding,在CircleView中的onDraw添加如下代码:
绘制时考虑传入padding属性值(4个方向)
// 仅看复写的onDraw()@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 获取传入的padding值 final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int paddingTop = getPaddingTop(); final int paddingBottom = getPaddingBottom(); // 获取绘制内容的高度和宽度(考虑了四个方向的padding值) int width = getWidth() - paddingLeft - paddingRight ; int height = getHeight() - paddingTop - paddingBottom ; // 设置圆的半径 = 宽,高最小值的2分之1 int r = Math.min(width, height)/2; // 画出圆(蓝色) // 圆心 = 控件的中央,半径 = 宽,高最小值的2分之1 canvas.drawCircle(paddingLeft+width/2,paddingTop+height/2,r,mPaint1); }
这时候在 xml的view中添加 android:padding="20dp",view就会支持padding了
(3)提供自定义属性:
// 基本是以android开头 android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000" android:padding="30dp"
上面是系统自带的自定义属性。 但有时候我们需要定义系统所没有的属性,称为自定义属性,实现步骤有下: ①、在values目录下自定义属性的xml文件 ②、在自定义view的构造方法中解析自己定义属性的值 ③、在布局文件中自己定义属性
具体实现: ①:在values中定义xml文件:attrs_circle_view.xml
对于自定义属性类型有如下格式:
<-- 1. reference:使用某一资源ID -->
②、在自定义view的构造方法中解析自定义的属性值: 这里要解析"circle_color"这个值
// 该构造函数需要重写 public CircleView(Context context, AttributeSet attrs) { this(context, attrs,0); // 原来是:super(context,attrs); init();public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // 加载自定义属性集合CircleView TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CircleView); // 解析集合中的属性circle_color属性 // 该属性的id为:R.styleable.CircleView_circle_color // 将解析的属性传入到画圆的画笔颜色变量当中(本质上是自定义画圆画笔的颜色) // 第二个参数是默认设置颜色(即无指定circle_color情况下使用) mColor = a.getColor(R.styleable.CircleView_circle_color,Color.RED); // 解析后释放资源 a.recycle(); init(); }
这样,默认情况下为:
这样一个自定义View就实现了。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~