这几天一直在学习自定义View,跟着鸿洋的博客做了自定义控件入门的例子,今天也来说说自定义控件的那些事。
我们之所以要自定义控件,就是因为android提供的默认控件不符合我们实际的需求,我们需要给控件加上我们需要的属性。自定义view在开发中使用很多,对于我这种新手程序员来说学好还是很重要的。
首先我们来了解一下自定义控件的大概的步骤。
1。自定义的属性
2。在View的构造方法中取得自定义的属性。
3。重写onMeasure方法
4。重写onDraw方法
1。自定义的属性
我们需要在res/values下面新建xml文件,书写我们的自定义属性,类似下面的代码
<span style="font-family: 'Microsoft YaHei';"><span style="font-size: 24px;"> <resources>
<attr name="titleText" format="string" />
<attr name="titleTextColor" format="color" />
<attr name="titleTextSize" format="dimension" />
<declare-styleable name="CustomView">
<attr name="titleText" />
<attr name="titleTextColor" />
<attr name="titleTextSize" />
</declare-styleable>
</resources></span></span>
2。在View的构造方法中取得自定义的属性。
新建一个CustomView的类,继承View,重写三个构造方法。 在我们三个参数的构造方法中初始化自定义属性的值并且初始化相关对象。
public CustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, defStyle, 0);
int n = a.getIndexCount();
mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(R.styleable.CustomView_image1, 0));
mImageScale = a.getInteger(R.styleable.CustomView_imageScaleType1, 0);
mTitle = a.getString(R.styleable.CustomView_titleText1);
mTextColor = a.getColor(R.styleable.CustomView_titleTextColor1, Color.BLACK);
mTextSize = a.getDimensionPixelSize(R.styleable.CustomView_titleTextSize1, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16,
getResources().getDisplayMetrics()));
a.recycle();
rect = new Rect();
mPaint = new Paint();
mTextRect = new Rect();
mPaint.setTextSize(mTextSize);
//计算描绘字体需要的范围
mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTextRect);
}
3。重写onMeasure方法
之前已经说过onMeasure方法的使用,这里就不多说,具体可以参考简单聊聊onMeasure。
4。重写onDraw方法
Ondraw方法就是在画布上绘制View,在调用之前我们已经测量过View,这里就可以取得View的相关属性进行绘制,通过
<span style="font-size:18px;">getMeasuredWidth()</span>
和
<span style="font-size:18px;">getMeasuredHeight()</span>
进行获得View的宽和高。这里涉及到一些画笔和画布等等的问题,这篇就不详细解释。
Ps:还存在一个疑问,就是getMeasureWidth和getWidth的使用区别,在ondraw中调用是相同的结果。还知道在oncreat方法中无法直接getwidth,要先进行测量,但是这两个方法有什么使用的差别呢,查了网上的一些资料还是有些不明白,希望有人可以指点一些。