Android 自定义View教程(3)

继续我们的自定义View之旅。 今天要实现的效果

首先我们看到这样的效果,如果是你,你会怎么去实现,我们来分析下,需要哪些属性。

  1. 2种颜色
  2. 速度
  3. 圆环的宽度
  4. 是否圆环交替显示

老规矩先自定义我们的属性:

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

<declare-styleable name="Myview">
    <attr name="OneColor" format="color"/>
    <attr name="TwoColr" format="color"/>
    <attr name="CriWidth" format="dimension"/>
    <attr name="speed" format="integer"/>
    <attr name="ring" format="boolean"/>
</declare-styleable>

</resources>

接着我们在布局中使用我们自定义的属性:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_horizontal"
android:orientation="vertical">

<com.linchaokun.customview3.view.MyView
    android:layout_width="300dp"
    android:layout_height="0dp"
    android:layout_weight="1"
    app:OneColor="@color/colorAccent"
    app:TwoColr="@color/colorPrimary"
    app:CriWidth="30dp"
    app:speed="10"/>

<com.linchaokun.customview3.view.MyView
    android:layout_width="300dp"
    android:layout_height="0dp"
    android:layout_weight="1"
    app:OneColor="@color/colorAccent"
    app:TwoColr="@color/colorPrimary"
    app:CriWidth="30dp"
    app:speed="10"
    app:ring="true"/>
</LinearLayout>

这里一个画饼图,一个画圆环交替效果(app:ring="true")。

接下来就是我们的重点自定义的View:

package com.linchaokun.customview3.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import com.linchaokun.customview3.R;

/**
 * 作者:linchaokun on 2016/7/31 20:46
 * 邮箱:812086325@qq.com
 */
public class MyView extends View{

//第一个圆的颜色
private int mOneColor;
//第二个圆的颜色
private int mTwoColor;
//圆环的宽度
private int mCriWidth;
//速度
private int mSpeed;
//是否开始下一个
private boolean isNext = false;

//当前进度
private int mProgress;

//是否圆环交替
private boolean mRing;
//画笔
private Paint mPaint;



public MyView(Context context) {
    this(context,null);
}

public MyView(Context context, AttributeSet attrs) {
    this(context, attrs,0);
}

public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.Myview, defStyleAttr, 0);

    //第一个圆颜色
    mOneColor = array.getColor(R.styleable.Myview_OneColor, getResources().getColor(R.color.colorAccent));
    //第二个圆的颜色
    mTwoColor = array.getColor(R.styleable.Myview_TwoColr,getResources().getColor(R.color.colorPrimaryDark));
    //圆环的宽度
    mCriWidth = array.getDimensionPixelSize(R.styleable.Myview_CriWidth, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
    //圆环速率
    mSpeed = array.getInteger(R.styleable.Myview_speed,0);
    //是否圆环交替
    mRing = array.getBoolean(R.styleable.Myview_ring,false);


    array.recycle();

    initPaint();

    initThread();

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    int centre = getWidth() / 2; // 获取圆心的x坐标
    int radius = centre - mCriWidth / 2;// 半径

    mPaint.setStrokeWidth(mCriWidth); // 设置圆环的宽度
    mPaint.setAntiAlias(true); // 消除锯齿
    if(mRing){
        mPaint.setStyle(Paint.Style.STROKE); // 设置空心
    }else{
        mPaint.setStyle(Paint.Style.FILL); // 设置实心
    }

    RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限
    if (!isNext)
    {// 第一颜色的圈完整,第二颜色跑
        mPaint.setColor(mOneColor); // 设置圆环的颜色
        canvas.drawCircle(centre, centre, radius, mPaint); // 画出圆环
        mPaint.setColor(mTwoColor); // 设置圆环的颜色
        canvas.drawArc(oval, -90, mProgress, mRing?false:true, mPaint); // 根据进度画圆弧
    } else
    {
        mPaint.setColor(mTwoColor); // 设置圆环的颜色
        canvas.drawCircle(centre, centre, radius, mPaint); // 画出圆环
        mPaint.setColor(mOneColor); // 设置圆环的颜色
        canvas.drawArc(oval, -90, mProgress, mRing?false:true, mPaint); // 根据进度画圆弧
    }

}


private void initThread() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true){
                mProgress++;
                if(mProgress==360){
                    mProgress=0;
                    if(!isNext){
                        isNext=true;
                    }else{
                        isNext=false;
                    }
                }

                postInvalidate();
                try {
                    Thread.sleep(mSpeed);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }).start();
}

private void initPaint() {
    mPaint = new Paint();
    mPaint.setAntiAlias(true);

}
}

我们还是构造方法互调,在第三个构造方法写我们的代码。

构造方法我们获取到我们自定义的属性值,初始化我们的画笔,这里还初始化了一个线程。

相信看过前面文章的都很容易看懂本节课的内容,注释也写的听清楚了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值