Android自定義View之CircleView

Android自定義View之CircleView

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。html

轉載請代表出處:http://www.cnblogs.com/cavalier-/p/5999037.htmljava

前言

你們好,我是Cavalier,此次和你們分享一下《Android自定義View之CircleView》,不廢話,下面上效果圖。android

Alt text

分析

需求canvas

1:隨機換顏色的一個view  
2:能夠設置文字

動手

Setup1:繼承自View,重寫三個構造函數dom

public class CircleView extends View {
    public CircleView(Context context) {
        this(context,null);
    }

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

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

上面代碼中重寫了三個構造函數,其中第一個是用於直接new對象,第二個是從xml建立時沒有指定style時調用,第三個是指定了style時調用,經過this能夠直接指向第三個構造參數,全部初始化能夠直接寫在第三個構造參數中ide

Setup2:聲明所需的變量函數

private Paint mTextPain;                        //初始化畫筆
private String mText = "";                      //初始化文字
private int radius;                             //當前View的半徑

...
 public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    configPaint();
}
  
private void configPaint() {
    mTextPain = new Paint();
    mTextPain.setColor(Color.WHITE);            //設置畫筆顏色爲白色
    mTextPain.setAntiAlias(true);               //開啓抗鋸齒,平滑文字和圓弧的邊緣
    mTextPain.setTextAlign(Paint.Align.CENTER); //設置文本位於相對於原點的中間
}

上面代碼在第三個構造函數調用了configPaint函數字體

Setup3:從新onDraw函數ui

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    int width = getWidth() / 2;                                 //獲取寬度一半
    int height = getHeight() / 2;                               //獲取高度一半
    radius = Math.min(width, height);                           //設置半徑爲寬或者高的最小值
    //paint bg
    mTextPain.setColor(Color.parseColor(getRandomColor()));     //設置畫筆顏色爲隨機顏色
    canvas.drawCircle(width, height, radius, mTextPain);        //利用canvas畫一個圓

    //paint font
    mTextPain.setColor(Color.WHITE);                            //設置畫筆白顏色
    mTextPain.setTextSize(dp2px(16));                           //設置字體大小爲16dp
    Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //獲取字體測量對象
    canvas.drawText(mText, 0, mText.length(), radius            //利用canvas畫上字
            , radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain);
}

上面代碼中先獲取到當前view的寬和高,取其中最小值做爲背景的半徑,設置了隨機顏色作背景,且利用FontMetrics獲取了文字的繪製位置this

Setup4:添加兩個輔助函數,dp2px和getRandomColor

/**
 * 給View設置文字
 * @param str
 */
public void setText(String str) {
    if(!TextUtils.isEmpty(str)){
        if(str.length()>1){
            mText = str.substring(0,1);
        }else {
            mText = str;
        }
    }else {
        mText =  "";
    }
    invalidate();
}

固然,咱們須要將設置文字暴露給使用者,這裏利用了invalidate讓CircleView從新繪製一遍,目的是更改內中的文字

Setup5:添加兩個輔助函數,dp2px和getRandomColor

/**
 * dp轉px
 *
 * @param dp
 * @return
 */
private int dp2px(int dp) {
    // px = dp * (dpi / 160)
    DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
    int dpi = metrics.densityDpi;
    return (int) (dp * (dpi / 160f) + 0.5f);
}


/**
 * 獲取隨機顏色
 *
 * @return
 */
private String getRandomColor() {
    List<String> colorList = new ArrayList<String>();
    colorList.add("#303F9F");
    colorList.add("#FF4081");
    colorList.add("#59dbe0");
    colorList.add("#f57f68");
    colorList.add("#f8b552");
    colorList.add("#990099");
    colorList.add("#90a4ae");
    colorList.add("#7baaf7");
    colorList.add("#4dd0e1");
    colorList.add("#4db6ac");
    colorList.add("#aed581");
    colorList.add("#fdd835");
    colorList.add("#f2a600");
    colorList.add("#ff8a65");
    colorList.add("#f48fb1");
    colorList.add("#7986cb");
    colorList.add("#DEB887");
    colorList.add("#FF69B4");
    return colorList.get((int) (Math.random() * colorList.size()));
}

補充了這兩個輔助函數後,代碼已經完成了

How to use?

在XML中使用

...

<com.ram.testdemo.view.CircleView
    android:id="@+id/cv"
    android:layout_width="50dp"
    android:layout_height="50dp"/>

...

這裏注意調用時是使用你本身的Class文件全路徑。

在java中使用

CircleView mCircleView = (CircleView) findViewById(R.id.cv);
mCircleView.setText("哈哈");

Souce Code

public class CircleView extends View {
    private Paint mTextPain;                        //初始化畫筆
    private String mText = "";                      //初始化文字
    private int radius;                             //當前View的半徑

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

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

    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        configPaint();
    }

    private void configPaint() {
        mTextPain = new Paint();
        mTextPain.setColor(Color.WHITE);            //設置畫筆顏色爲白色
        mTextPain.setAntiAlias(true);               //開啓抗鋸齒,平滑文字和圓弧的邊緣
        mTextPain.setTextAlign(Paint.Align.CENTER); //設置文本位於相對於原點的中間
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth() / 2;                                 //獲取寬度一半
        int height = getHeight() / 2;                               //獲取高度一半
        radius = Math.min(width, height);                           //設置半徑爲寬或者高的最小值
        //paint bg
        mTextPain.setColor(Color.parseColor(getRandomColor()));     //設置畫筆顏色爲隨機顏色
        canvas.drawCircle(width, height, radius, mTextPain);        //利用canvas畫一個圓

        //paint font
        mTextPain.setColor(Color.WHITE);                            //設置畫筆白顏色
        mTextPain.setTextSize(dp2px(16));                           //設置字體大小爲16dp
        Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //獲取字體測量對象
        canvas.drawText(mText, 0, mText.length(), radius            //利用canvas畫上字
                , radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain);
    }

    /**
     * 給View設置文字
     * @param str
     */
    public void setText(String str) {
        if(!TextUtils.isEmpty(str)){
            if(str.length()>1){
                mText = str.substring(0,1);
            }else {
                mText = str;
            }
        }else {
            mText =  "";
        }
        invalidate();
    }

    /**
     * dp轉px
     *
     * @param dp
     * @return
     */
    public int dp2px(int dp) {
        // px = dp * (dpi / 160)
        DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
        int dpi = metrics.densityDpi;
        return (int) (dp * (dpi / 160f) + 0.5f);
    }



    /**
     * 獲取隨機顏色
     *
     * @return
     */
    private String getRandomColor() {
        List<String> colorList = new ArrayList<String>();
        colorList.add("#303F9F");
        colorList.add("#FF4081");
        colorList.add("#59dbe0");
        colorList.add("#f57f68");
        colorList.add("#f8b552");
        colorList.add("#990099");
        colorList.add("#90a4ae");
        colorList.add("#7baaf7");
        colorList.add("#4dd0e1");
        colorList.add("#4db6ac");
        colorList.add("#aed581");
        colorList.add("#fdd835");
        colorList.add("#f2a600");
        colorList.add("#ff8a65");
        colorList.add("#f48fb1");
        colorList.add("#7986cb");
        colorList.add("#DEB887");
        colorList.add("#FF69B4");
        return colorList.get((int) (Math.random() * colorList.size()));
    }
}

結尾

本篇中,咱們掌握了自定義View的invalidate重繪,和FontMetrics的文本位置測量,還了解onDraw中的canvas的用法。如文中有描述不巧當的地方請指出,謝謝。

參考 : Android custom-components

相關文章
相關標籤/搜索