1. 首先应该先考虑:
是继承 View ,还是ViewGroup ,还是继承一个具体控件(textView,LinearLayout)
2. 考虑自定义属性:
补:自定义View的属性的步骤
①自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomTitleView">
<attr name="titleText" />
<attr name="titleTextColor" />
<attr name="titleTextSize" />
</declare-styleable>
</resources>
②在布局文件中引用当前应用的名称空间
xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"
③在自定义视图标签中使用自定义属性
④在自定义View类的构造方法中, 取出布局中的自定义属性值
//得到所有自定义属性的数组
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.CustomTitleView_titleText:
mTitleText = a.getString(attr);
break;
case R.styleable.CustomTitleView_titleTextColor:
// 默认颜色设置为黑色
mTitleTextColor = a.getColor(attr, Color.BLACK);
break;
case R.styleable.CustomTitleView_titleTextSize:
// 默认设置为16sp,TypeValue也可以把sp转化为px
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
3. 重写其相关回调方法:
onFinishInflite()或onAttachToWindow(): 得到子View对象
onMeasure(): 通过测量得到子View的宽高
注意: 如果对View的宽高进行修改了,不要调用super.onMeasure( widthMeasureSpec, heightMeasureSpec); 而要调用 setMeasuredDimension( widthsize, heightsize); 这个函数。
思考: 为什么要测量View大小?
答:View的大小不仅由自身所决定,同时也会受到父控件的影响,为了我们的控件能更好的适应各种情况,一般会自己进行测量。
规则可参看下表:
onSizeChanged(): 确定View大小,这个函数在视图大小发生改变时调用。
onLayout(): 确定布局的函数,它用于确定子View的位置。
注意:在自定义ViewGroup中会用到,他调用的是子View的layout函数。onLayout一般是循环取出子View,然后经过计算得出各个子View位置的坐标值,然后用chid.layout(l,t,r,b)函数设置子View位置。
onDraw(): 进行绘制。