打算好好学一学自定义控件,然后就尽量写一下连载博客吧
先从自定义View开始
- 先说一下今天的自定义VIew实现的功能
- 就是像TextView一样能显示文字,即可
- 贪多嚼不烂,一步一步慢慢来
一,定义自己View的属性
- 当我们需要使用一个成品View的时候,总会在xml文件里面设置它的好多好多属性,所以第一步先来看看自定义属性吧
- 在value文件夹下的attrs.xml(没有这个文件则新建)文件下,创建新的declare-styleable结点,然后在这个结点中写上自己想要定义的属性,如下
<declare-styleable name="MyTextView">
<attr name="titleText" format="string"/>
<attr name="titleTextColor" format="color"/>
<attr name="titleTextSize" format="dimension"/>
</declare-styleable>
- declare-styleable结点后的name跟的是你的定义的view的名字
- 内部子项的name是你打算定义的属性的名字,后面的format是你这个属性的类型
二,自定义View类
- 定义自己的View类,他可以继承自现成的View,也可以直接继承View或者VIewGroup
- 我先定义一个继承自View的类,这样我们的VIew内容就可以自行发挥了
- 然后在类里面,有几个方法需要重写,今天关注的是构造函数,onMeasure(),onDraw()这三个方法
- 第一个构造函数是在生成View的时候调用,从构造方法中我们可以得到别人写在xml文件中对我们的VIew的一些属性的设置参数
- 第二个方法测量,顾名思义,主要负责测量我们View的大小的
- 第三个方法绘制,就是绘制出我们的View啦
- 由于我只是第一次写自定义View,第一次就先写这么多吧,接下来看一下代码
public class MyTextView extends View{
private String mTitleText;
private int mTitleTextColor;
private int mTitleTextSize;
/**
* 绘制时控制文本的的绘制范围,一个矩形,刚好能装下设置的文字的大小,就是说一个矩形刚好装下一个文字
*/
private Rect mBound;
private Paint mPaint;
public MyTextView(Context context) {
this(context,null);
}
public MyTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTextView,defStyleAttr,0);
int n = typedArray.getIndexCount();
for (int i = 0;i < n;i++){
int attr = typedArray.getIndex(i);
switch (attr){
case R.styleable.MyTextView_titleText:
mTitleText = typedArray.getString(attr);
break;
case R.styleable.MyTextView_titleTextColor:
mTitleTextColor = typedArray.getColor(attr, Color.BLACK);
break;
case R.styleable.MyTextView_titleTextSize:
mTitleTextSize = typedArray.getDimensionPixelSize(attr,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,
getResources().getDisplayMetrics()));
break;
}
}
typedArray.recycle();
mPaint = new Paint();
mPaint.setColor(mTitleTextColor);
mPaint.setTextSize(mTitleTextSize);
mBound = new Rect();
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
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();
width = (int)(getPaddingLeft() + textWidth + getPaddingRight());
}
if( heightMode == MeasureSpec.EXACTLY){
height = heightSize;
}else {
mPaint.setTextSize(mTitleTextSize);
mPaint.getTextBounds(mTitleText,0,mTitleText.length(),mBound);
float textHeight = mBound.height();
height = (int)(getPaddingTop() + textHeight + getPaddingBottom());
}
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
mPaint.setColor(Color.BLUE);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);
mPaint.setColor(mTitleTextColor);
canvas.drawText(mTitleText,getWidth()/2 - mBound.width()/2,getHeight()/2 + mBound.height()/ 2,mPaint);
}
}
- 大概就是这个简单的样子了,先获取参数,然后测量控件应该具有的大小,最后将这个控件画出来
- 嗯,因为时间原因,我明天再仔细探索一下其中一些参数的具体东西,具体细节将写在下一篇博客中
- 注:我是菜鸟,大神勿喷