Android 自定义View 带你飞(一)

本文介绍了自定义View的三种情况,并通过实现一个简单的计步器示例,详细讲解了如何定义属性、创建类继承View及在布局文件中使用自定义View。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习自定义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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值