如何自定义控件
- 自定义属性的声明与获取
- 测量onMeasure
- 布局onLayout(ViewGroup)
- 绘制onDraw
- onTouchEvent
- onInterceptTouchEvent
1.自定义属性声明与获取
(1) 分析需要的自定义属性
(2)在res/values/attrs.xml定义声明(文件名字可以随便取)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="icon1" format="reference"></attr>
<attr name="color1" format="color"></attr>
<attr name="text" format="string"></attr>
<attr name="text_size" format="dimension"></attr>
<declare-styleable name="ChangeColorIconWithText">
<attr name="icon1"></attr>
<attr name="color1"></attr>
<attr name="text"></attr>
<attr name="text_size"></attr>
</declare-styleable>
</resources>
(3)在layout xml文件中进行使用
(4)在View的构造方法中进行获取
通过下面的第一行即可获取,最获取完成后调用a.recyle()进行释放
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.ChangeColorIconWithText);
int n = a.getIndexCount();
for(int i = 0;i<n;i++)
{
int attr = a.getIndex(i);
switch (attr)
{
case R.styleable.ChangeColorIconWithText_icon1:
BitmapDrawable drawable = (BitmapDrawable)a.getDrawable(attr);
mIconBitmap = drawable.getBitmap();
break;
case R.styleable.ChangeColorIconWithText_color1:
mColor = a.getColor(attr,0xFF45C01A);
break;
case R.styleable.ChangeColorIconWithText_text:
mText = a.getString(attr);
break;
case R.styleable.ChangeColorIconWithText_text_size:
mTextSize = (int)a.getDimension(attr,TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,12,getResources().getDisplayMetrics()));
break;
}
}
a.recycle();
2.测量onMeasure
(1)测量由两个数字决定,意识测量的模式,二是测量的值。
(2)测量的模式:EXACTLY(明确的值)、AT_MOST(最多不能超过某个值)、UNSPECIFIED(没有限制,主要用于Listview scrollView)
(3)MeasureSpec:模式和值一般会封装成一个MeasureSpec,是在onMeasure中父控件传下来的,通过
MeasureSpec.getMode() 获取mode
MeasureSpec.getSize() 获取Size
(4)setMeasureDimension:当测量完毕以后,不要忘记调用setMeasureDimension把最终得到的result传进去
(5)requestLayout()触发测量
3.布局onLayout(ViewGroup)
父控件去决定子控件的显示位置,单独定义一个View是没有的
(1)决定子View的位置
(2)尽可能将onMeasure中一些操作移动到此方法中
(3)requestLayout()
4.onDraw
(1)绘制内容区域
(2)invalidate()在UI线程中调用用力啊重绘.
postInvalidate();在子线程中调用用来重绘
/**
* 重绘
*/
public void invalidateView()
{
if (Looper.getMainLooper() == Looper.myLooper())//判断是否是在UI线程
{
invalidate();
}
else
{
postInvalidate();
}
}
(3)Canvas.drawXXX熟练使用这些方法
(4)translate,rotate,scale,skew
(5)save(),restore()