
自定义View可以分为两大类,一种是自定义View,一种是自定义ViewGroup;其中自定义View又分为继承View和继承系统控件两种。
这种自定义View在系统控件的基础上进行拓展,一般是添加新的功能或者修改显示的效果,一般情况下我们在onDraw()方法中进行处理
自定义view时只需要重写onMeasure()和onDraw()
自定义viewGroup时只需要重写onMeasure()和onLyaout()
public class MyTextView extends View {
//当在代码中创建一个 View 的时候使用
//这个构造函数就是在代码中直接 new view 的时候使用,这样出来的 View 默认是没有任何的属性值,需要后面自己手动 set。
public MyTextView(@NonNull Context context) {
super(context);
}
//当我们在 xml 中定义了 View 然后在代码中使用这个 View 的时候,这个 View 就是利用这个构造方法生成的。
//View 的属性值来自 AttributeSet 的值
//这个构造函数是在代码中生成对应 xml 中定义的 View 使用的。这个时候在 xml 中定义的属性值会通过 AttributeSet 传递,这样生成的 View 对象是有默认的属性值的
public MyTextView(@NonNull Context context,
@Nullable AttributeSet attrs) {
super(context, attrs);
}
//这个构造方法就是提供了默认的 defStyleAttr 用于指定基本的属性
//这个构造函数就是相对于第二个构造函数,多提供了一种给 View 添加默认属性的方式,通过 deftStyleAttr 如果没有默认的值,就用 0 。
public MyTextView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//第四个构造函数相对第三个构造函数就多了一个 defStyleRes ,说白了就是多了一种提供 View 默认属性的一种方式。这种方式更加的简单,直接在代码中传入 R.style.XX 就可以了。如果没有默认值的话就为 0 。这个参数只有 defStyleAttr 为 0 的时候才会生效。
public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
自定义属性
android系统的控件以android开头的比如android:layout_width,这些都是系统自带的属性,为了方便配置MyTextView的属性,我们也可以自定义属性,首先在values目录下创建 attrs.xml:
在构造方法中解析自定义view的属性
public MyTextView(@NonNull Context context,
@Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);
typedArray.getColor(R.styleable.MyTextView_textcolor,1);
//获取资源后要及时回收
typedArray.recycle();
}
在xml里使用自定义属性
三个过程
三个动作对应的意义
测量:onMeasure()决定View的大小;
布局:onLayout()决定View在ViewGroup中的位置;
绘制:onDraw()决定绘制这个View。
1.MeasureSpec的Model可以分为以下三种模式:
2、getMeasureWidth与getWidth的区别
getMeasuredWidth
在measure()过程结束后就可以获取到对应的值;
通过setMeasuredDimension()方法来进行设置的。getWidth
在layout()过程结束后才能获取到;
通过视图右边的坐标减去左边的坐标计算出来的。
父视图与子视图的关系