1.特定的显示风格
2.处理特有的用户交互
3.优化我们的布局
4.封装等
如何自定义控件
1.自定义属性的声明与获取
2.测量onMeasure
3.绘制onDraw
4.状态的存储与恢复
自定义属性声明与获取
1.分析需要的自定义
2.再res/values/attrs.xml定义声明
3.在layout xml文件进行使用
4.在View的构造方法中进行获取
// 获取 xml声明的属性值
// 这种会丢失默认值
// 自定义属性的声明与获取
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.TestView);
boolean booleanTest = ta.getBoolean(R.styleable.TestView_test_boolean,false);
int integerTest = ta.getInteger(R.styleable.TestView_test_integer,1);
float dimensionTest = ta.getDimension(R.styleable.TestView_test_dimension,0);
int enumTest = ta.getInt(R.styleable.TestView_test_enum,1);
// mText = ta.getString(R.styleable.TestView_test_string); // null
// 这种不会影响村存量变量
int count = ta.getIndexCount();
for(int i =0;i<count;i++){
int index = ta.getIndex(i);
switch (index){
case R.styleable.TestView_test_string:
mText = ta.getString(R.styleable.TestView_test_string);
break;
}
}
Log.e("Tag",booleanTest+
","+integerTest+","
+dimensionTest+","+enumTest+","+mText);
ta.recycle();
//测量onMeasure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int width = 0;
if(widthMode == MeasureSpec.EXACTLY){
width = widthSize;
}else{
int needWidth = measureWidth() + getPaddingLeft() + getPaddingRight();
if(widthMode == MeasureSpec.AT_MOST){
width = Math.min(needWidth,widthSize);
}else{
width = needWidth;
}
}
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int height = 0;
if(heightMode == MeasureSpec.EXACTLY){
height = heightSize;
}else{
int needHeight = measureHeight() + getPaddingTop() + getPaddingBottom();
if(heightMode == MeasureSpec.AT_MOST){
height = Math.min(needHeight,heightSize);
}else{
height = needHeight;
}
}
setMeasuredDimension(width,height);
}
private int measureWidth(){
return 0;
}
private int measureHeight(){
return 0;
}