自定义View 总结
自定义View的步骤
1.自定义属性和声明与获取
1.分析需要的自定义属性
2.在res/values/attrs.xml定义声明
3.在layout xml文件中进行使用
4.在View的构造方法中进行获取
Tips:
2.测量onMeasure
对于普通View,MeasureSpec由父容器的MeasureSpec和自身的LayoutParams共同决定。对于顶级View,其MeasureSpec由窗口尺寸和其自身的LayoutParams来共同确定。在测量过程中,系统会将View的LayoutParams根据父容器所施加的规则转换成对应的Spec,然后再根据这个measureSpec来测量出View的宽/高。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, 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 { //MeasureSpec.UNSPECIFIED 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,widthSize); } else { height = needHeight; } } setMeasuredDimension(width, height); }
3.绘制onDraw
4.状态的存储与恢复
private static final String INSTANCE = "instance"; private static final String KEY_TEXT = "key_text"; @Override protected Parcelable onSaveInstanceState() { Bundle bundle = new Bundle(); bundle.putString(KEY_TEXT,mText); bundle.putParcelable(INSTANCE,super.onSaveInstanceState()); return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) { if(state instanceof Bundle) { Bundle bundle = (Bundle)state; Parcelable parcelable = bundle.getParcelable(INSTANCE); super.onRestoreInstanceState(parcelable); mText = bundle.getString(KEY_TEXT); return; } super.onRestoreInstanceState(state); }
注意为自定义设置id。
自定义View分类
1.继承View重写onDraw方法
需要自己支持wrap_content(参考上文onMeasure()中处理)。
在onDraw()时,要考虑padding处理。
2.继承ViewGroup派生特殊的Layout
3.继承特定的View
4.继承特定的ViewGroup