自定義view(一 )

本文轉載是看了鴻洋大神的自定義view自己跟着寫了一遍加上了一些註釋。如果想更詳細的瞭解請參考原文:http://blog.csdn.net/lmj623565791/article/details/24252901

1、自定義View的屬性

2、在View的構造方法中獲得我們自定義的屬性

[ 3、重寫onMesure ]

4、重寫onDraw

我把3用[]標出了,所以說3不一定是必須的,當然了大部分情況下還是需要重寫的。

1、自定義View的屬性,首先在res/values/  下建立一個attrs.xml , 在裏面定義我們的屬性和聲明我們的整個樣式。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomView">
        <attr name="customText" format="string" />
        <attr name="customTextColor" format="color" />
        <attr name="customTextSize" format="dimension" />
    </declare-styleable>
</resources>

我們定義了字體,字體顏色,字體大小3個屬性,format是值該屬性的取值類型:

一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;不清楚的可以google一把。

然後在佈局中聲明我們的自定義View

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

    <zdd.customview.hongyangview.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:padding="5dp"
        app:customText="點我有驚喜"
        app:customTextColor="#ff00ff"
        app:customTextSize="40sp" />
</RelativeLayout>
一定要引入 xmlns:custom="http://schemas.android.com/apk/res/com.example.customview01"(這個我的不行。不知道原因)或者
xmlns:app="http://schemas.android.com/apk/res-auto"
我們的命名空間,後面的包路徑指的是項目的package

2、在View的構造方法中,獲得我們的自定義的樣式

package zdd.customview.hongyangview;

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

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import zdd.customview.R;

/**
 * Created by ZDD on 2016/7/28.
 */
public class CustomView extends View implements View.OnClickListener {
    // 定義控件屬性值
    private String customText;
    private int customTextColor;
    private int customTextSize;

    // 定義畫筆
    private Paint paint;
    // 繪製矩形
    private Rect rect;

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

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

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
        // 獲取到自定義屬性的數量
        int arrChild = array.getIndexCount();
        for (int i = 0; i < arrChild; i++) {
            // 獲取到自定義屬性的索引值
            int child = array.getIndex(i);
            switch (child) {
                case R.styleable.CustomView_customText:
                    customText = array.getString(child);
                    break;
                case R.styleable.CustomView_customTextColor:
                    customTextColor = array.getColor(child, 0);
                    break;
                case R.styleable.CustomView_customTextSize:
                    customTextSize = (int) array.getDimension(child, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                    break;
            }
        }
        paint = new Paint();
        // 設置文字大小
        paint.setTextSize(customTextSize);
        // 初始化矩形
        rect = new Rect();
        // 根據填充的數據返回rect的具體寬高 第一個參數是文字,第二個參數是從0開始繪製 第三個參數是到文字的結束停止繪製, 第四個是矩形
        paint.getTextBounds(customText, 0, customText.length(), rect);

        // 添加點擊事件
        setOnClickListener(this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 獲取到設置的寬度類型和大小
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        // 獲取到設置的高度的類型和大小
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        // 定義寬高 記錄寬高
        int width = 0;
        int height = 0;

//        重寫之前先了解MeasureSpec的specMode,一共三種類型:
//        EXACTLY:一般是設置了明確的值或者是MATCH_PARENT
//        AT_MOST:表示子佈局限制在一個最大值內,一般爲WARP_CONTENT
//        UNSPECIFIED:表示子佈局想要多大就多大,很少使用

        if (widthMode == MeasureSpec.EXACTLY) {
            // 如果設置的是match_parent
            width = widthSize;
        } else {
            // 設置文字大小
            paint.setTextSize(customTextSize);
            // 將文字繪製到矩形上以便獲取到寬高 第一個參數是文字,第二個參數是從0開始繪製 第三個參數是到文字的結束停止繪製, 第四個是矩形
            paint.getTextBounds(customText, 0, customText.length(), rect);
            // 獲取到文字的寬度
            float textWidth = rect.width();
            // 將計算出的寬度告訴給屏幕
            width = (int) (getPaddingLeft() + textWidth + getPaddingRight());
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            // 如果設置的是match_parent
            height = heightSize;
        } else {
            // 設置文字大小
            paint.setTextSize(customTextSize);
            paint.getTextBounds(customText, 0, customText.length(), rect);
            float textHeight = rect.height();
            height = (int) (getPaddingTop() + textHeight + getPaddingBottom());
        }

        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 繪製背景色
        paint.setColor(Color.YELLOW);
        // 將背景色繪製到UI界面上  參數分別代表。左上右下的座標位置, 最後一個是畫筆
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), paint);

        // 繪製文字顏色
        paint.setColor(customTextColor);
        /**
         * 將文字繪製到界面上
         * 第一個參數是文字
         * 第二個參數是x座標
         * 第三個參數是y座標
         * 第四個參數是畫筆
         */
        canvas.drawText(customText, getWidth() / 2 - rect.width() / 2, getHeight() / 2 + rect.height() / 2, paint);
    }

    @Override
    public void onClick(View v) {
        customText = getRandom();
        invalidate();
    }

    // 獲取長度爲4的隨機數
    public String getRandom() {
        Random random = new Random();
        List<Integer> list = new ArrayList<>();
        while (list.size() < 8) {
            int ran = random.nextInt(10);
            list.add(ran);
        }

        StringBuffer buffer = new StringBuffer();
        for (Integer in : list) {
            buffer.append("" + in);
        }
        return buffer.toString();
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章