安卓复习之旅—自定义view(一)

今天开始复习一下自定义view相关的知识。
先上图看看效果吧:
这里写图片描述
额 好像奥运五环那几个字没有居中。。。先这样吧(嘿嘿)开始coding吧:
step1定义需要自定义的属性
在res/values/文件夹创建一个attrs.xml文件,在里面编辑需要的自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="textColor" format="color" />
    <attr name="textSize" format="dimension" />

    <declare-styleable name="FiveCricle">
        <attr name="textColor" />
        <attr name="textSize" />
    </declare-styleable>

</resources>

step2代码中定义需要的属性

// 圆环的画笔
    private Paint bluePain;
    private Paint greenPain;
    private Paint redPain;
    private Paint blackPain;
    private Paint yelloPain;
    //文本画笔
    private Paint textPain;
    // 画布的宽高
    private int mCanvasWidth, mCanvasHeight;
    // 圆的半径
    private int mRadius = 80;

    // 1. 自定义的一些属性并赋值
    /**
     * 文本的颜色
     */
    private int mTextColor = 0xff00ff00;
    /**
     * 文本的大小
     */
    private int mTextSize = 10;

step3构造方法中初始化画笔和自定义属性
先来看看构造方法:在View类中有四个构造函数,涉及到多个参数, Context:上下文, AttributeSet attrs: 从xml中定义的参数,
int defStyleAttr :当前Theme中的包含的一个指向style的引用.当我们没有给自定义View设置declare-styleable资源集合时,默认从这个集合里面查找布局文件中配置属性值.传入0表示不向该defStyleAttr中查找默认值. ,int defStyleRes : 指向Style的资源,仅在defStyleAttr为0或者defStyleAttr不为0但Theme中没有为defStyleAttr属性赋值时起作用.
这里我们重写前两个参数;

// 在代码中直接new一个Custom View实例的时候,会调用第一个构造函数.
    public FiveCricle(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        initPain();

    }

    // 在xml布局文件中调用自定义属性的时候,会调用第二个构造函数.
    public FiveCricle(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        /**
         * 获取自定义属性并设置初始值
         */
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FiveCricle);
        int n = ta.getIndexCount();

        for (int i = 0; i < n; i++) {
            int attr = ta.getIndex(i);
            switch (attr) {
            case R.styleable.FiveCricle_textColor:
                mTextColor = ta.getColor(attr, mTextColor);
                break;
            case R.styleable.FiveCricle_textSize:
                mTextSize = ta.getDimensionPixelOffset(attr, mTextSize);
                break;

            }

        }
        //记得回收哦
        ta.recycle();
        initPain();
    }

初始化画笔

这里写代码片
bluePain = new Paint();
        bluePain.setColor(0xff00ff00);
        bluePain.setAntiAlias(true);
        bluePain.setStyle(Paint.Style.STROKE);
        bluePain.setStrokeWidth(10f);
    // 绘制文字的画笔
        textPain = new Paint();
        textPain.setAntiAlias(true);
        textPain.setStyle(Paint.Style.FILL);

自定义view的流程先计算onMeasure()方法—>onLayout()—>
onDraw()
step4重写onmeasure方法
一个MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求。 一个MeasureSpec由大小和模式组成。它有三种模式:UNSPECIFIED(未指定), 父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;EXACTLY(完全), 父元素决定自元素的确切大小, 子元素将被限定在给定的边界里而忽略它本身大小; AT_MOST(至多),子元素至多达到指定大小的值。

// 根据提供的测量值(格式)提取模式(上述三个模式之一)
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int desiredWidth, desiredHeight;
        if (widthMode == MeasureSpec.EXACTLY) {//确切的值或者match
            desiredWidth = widthSize;
        } else {
            desiredWidth = mRadius * 2 * 4 + getPaddingLeft() + getPaddingRight();
            if (widthMode == MeasureSpec.AT_MOST) {//wrap
                desiredWidth = Math.min(widthSize, desiredWidth);
            }
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            desiredHeight = heightSize;
        } else {
            desiredHeight = mRadius * 2 * 3 + getPaddingTop() + getPaddingBottom();
            if (heightMode == MeasureSpec.AT_MOST) {
                desiredHeight = Math.min(heightSize, desiredHeight);
            }
        }
        setMeasuredDimension(mCanvasWidth = desiredWidth, mCanvasHeight = desiredHeight);

step5重写onDraw()

//设置画布的背景
        mCanvas.drawColor(Color.WHITE);
        // 将坐标系原点移至去除内边距后的画布中心
        mCanvas.translate(mCanvasWidth * 1.0f / 2 + getPaddingLeft() - getPaddingRight(),
                mCanvasHeight * 1.0f / 2 + getPaddingTop() - getPaddingBottom());
        // 设置参数就可以将xml中的属性起作用
        textPain.setColor(mTextColor);
        textPain.setTextSize(mTextSize);
        mCanvas.drawCircle(-180, 0, mRadius, redPain);
        mCanvas.drawCircle(0, 0, mRadius, bluePain);
        mCanvas.drawCircle(180, 0, mRadius, greenPain);
        mCanvas.drawCircle(-90, 80, mRadius, yelloPain);
        mCanvas.drawCircle(100, 80, mRadius, blackPain);
        mCanvas.drawText("奥运五环", -80, -130, textPain);

step6最后编辑xml

<com.example.mycustomview.FiveCricle
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:textColor="#0000ff"
        custom:textSize="20sp" >
    </com.example.mycustomview.FiveCricle>

okay,至此一个简单的自定义view就实现了
下载地址:http://download.csdn.net/my

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值