Android的自定义View(2)
介绍了一些基础的知识,下面我们开始自定义View。
自定义View的步骤:
- 自定义View的属性
- 创建类文件,添加构造方法,获取属性并初始化变量
- 重写onMesure方法
- 重写onDraw方法
一.自定义View的属性
自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
不过现在的Android Studio在创建View的时候会自动生成这个attrs.xml文件。
里面有默认的属性,我们也可以自己添加,挺方便。
二.创建类文件,添加构造方法,获取属性并初始化变量
同样,我们在创建完一个View之后,也会生成类文件,里面很多方法变量上面的都已经写好了,等你自己去修改实现就可以了。
然后我们来看一下这里面的构造方法,一共有四个。
第一个构造方法,只有一个参数,如果View是在Java代码里面new的,则调用第一个构造函数。
public CustomTitleView(Context context) {
super(context); }
第二个构造方法,两个参数,如果View是在.xml里声明的,则调用第二个构造函数,自定义属性是从AttributeSet参数传进来的。
public CustomTitleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
第三个构造方法,三个参数,不自动调用,一般是在第二个构造函数里主动调用,如有style属性。
第四个构造方法,四个参数,API 21(5.0)之后才使用,和第三个构造方法一样,不自动调用。
然后我们再来获取属性,并初始化变量。
用一个数组来储存我们的属性。
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyleAttr, 0);
然后我们再获得这个数组里的各种属性,并且为他们设置默认值。
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyleAttr, 0);
for (int i = 0; i < a.getIndexCount(); 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:
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
}
}
a.recycle();//使用完务必回收。
初始化画笔:
private mpaint =new Paint(); //为了后面的绘制
三.重写onMesure方法
测量view,确定view的尺寸。(这步并不是自定义view的必要步骤,但重写后可以适应wrap_content这参数等)
这一步因为不是必须,可以跳过,但当你在设置layout_width和layout_height的时候只能设match_parent或指定值,不然设置wrap_content会很别扭。
下面是一个重写后的onMeasure方法,可以根据自己的需要去重写。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
mPaint.setTextSize(mTitleTextSize);
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
float textWidth = mBound.width();
int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
width = desired;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
mPaint.setTextSize(mTitleTextSize);
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
float textHeight = mBound.height();
int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
height = desired;
}
setMeasuredDimension(width, height);
}
四.重写onDraw方法
现实中你想要画一幅画,就必须要一个画布和一个画笔。
自定义View也是一样,Canvas就是画布,Paint就是画笔。Canvas和Patint有各种各样的属性。
(个人理解:Paint设置的是画的时候的各种属性,大小啦,颜色啦,粗体,透明度等等。画的话还是由Canvas完成)
由于这方面比较基础,可操作性强,但是比较复杂,所以这里不细写。
可以看这个网址,写的很详细了。
(http://www.gcssloop.com/customview/Canvas_BasicGraphics)