学习自定义View已经有一段时间了,下面手把手教大家入门自定义:
一、首先我们需要知道,自定义View分为三种情形:
1:直接继承View,就是自己来绘制我们需要的东西,主要涉及的方法就是onDraw(Canvas canvas);
2 : 组合控件,这种比较简单,比如自定义一个标题栏就可以用组合控件来写;
3:继承已有的控件,比如继承ImageView,TextView等;
二、接下来我们来实现具体的代码,写一个简单的计步器
1.自定义View的属性,首先在res/values/ 下建立一个attrs.xml ,在这里面写我们的View需要的属性
<declare-styleable name="CountView">
<attr name="titleText" format="string"/>
<attr name="titleTextSize" format="dimension"/>
<attr name="titleTextColor" format="color"/>
</declare-styleable>
这里的format表示你所定义的属性的赋值类型:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;
2.我们定义一个类继承View,这里我们叫做CountView,然后需要重写它的构造方法:
一般我们用到的是三种构造方法,具体含义如下:
//一个参数的构造方法通常是在实例化的时候使用,直接传入Context上下文对象,比如: CountView view = new CountView(this);
public CountView(Context context) {
super(context);
}
//带有两个参数的构造方法是在layout.xml文件里面实例化的时候使用,attrs表示的就是你定义的属性值
public CountView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//带有三个参数的构造方法多了一个defStyleAttr参数,是在布局文件你定义的那个style属性用到
public CountView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
其实还有一个四个参数的构造方法,但是我们一般是用不到的,我也不知道是干嘛的。。
然后我们在布局文件里面使用这个View
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ly="http://schemas.android.com/apk/res-auto"//这个是必须要的 你所定义的view的命名空间 app这个是空间名 你可以随意指定
android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingTop="10dp"
>
<com.android.app.consumeview.CountView android:layout_width="wrap_content"
android:layout_height="wrap_content"
ly:titleText="11"
ly:titleTextColor="@color/colorAccent"
ly:titleTextSize="15sp"/>
</LinearLayout>
3.在构造函数中获取我们定义的属性:
public class CountView extends View implements View.OnClickListener {
private static final int DEFAULT_COLOR = Color.parseColor("#3F51B5");
private static final int DEFAULT_SIZE = 16;
private String mTitleText;
private int mTitleTextSize;
private int mTitleColor;
private Paint mPaint;
private Rect mBoundRect;
public CountView(Context context) {
this(context, null);
}
public CountView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CountView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CountView, defStyleAttr, 0);
int count = a.getIndexCount();
for (int i = 0; i < count; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.CountView_titleText:
mTitleText = a.getString(attr);
break;
case R.styleable.CountView_titleSize:
//转化为sp
mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, DEFAULT_SIZE, getResources().getDisplayMetrics()));
break;
case R.styleable.CountView_titleColor:
mTitleColor = a.getColor(attr, DEFAULT_COLOR);
break;
}
}
a.recycle();
setOnClickListener(this);
initPaint();//初始化画笔
}
private void initPaint() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBoundRect = new Rect();
mPaint.setTextSize(mTitleTextSize);
mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBoundRect);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.GREEN);
Rect rect = new Rect(0, 0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRect(rect, mPaint);
mPaint.setColor(mTitleColor);
canvas.drawText(mTitleText, getWidth()/2 - mBoundRect.width() / 2, getHeight()/2 + mBoundRect.height() / 2, mPaint);
}
@Override
public void onClick(View v) {
mTitleText = String.valueOf(Integer.valueOf(mTitleText)+1);
invalidate();
}
}
转载请注明出处:http://blog.youkuaiyun.com/dreamfree3/article/details/52117392