1.自定义view入门

1.继承自view

系统提供的view 如 TextView 、ImageView 都是继承自view的;

2.自定义一个TextView

通过自定义一个TextView 来熟悉继承自view 的自定义view的api用法

3.onMeasure

用来处理控件的大小

 	@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    }
//获取宽高的模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);    

//mode
//MeasureSpec.AT_MOST 指定了wrap_content
//MeasureSpec.EXACTLY 指定了确切的值 match_parent fill_parent
//MeasureSpec.UNSPECIFIED 尽可能的大 

4.onDraw

用于绘制

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

5.onTouchEvent

用于处理用户触摸事件

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                break;
        }

        return super.onTouchEvent(event);
    }

6.自定义属性

用来配置自定义控件的属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--    自定义控件的名称 name="TextView"-->
    <declare-styleable name="TextView">
        <attr name="text" format="string" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="maxLength" format="integer" />
        <attr name="background" format="reference|color" />

        <!--枚举-->
        <attr name="inputType" format="enum">
            <enum name="number" value="1" />
            <enum name="text" value="2" />
            <enum name="password" value="3" />
        </attr>
    </declare-styleable>
</resources>

在布局中使用

<com.nb.customview.TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:text="张三"
    app:textColor="@color/purple_500"
    app:textSize="16" />

在自定义控件中获取

    public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextView);
        mText = typedArray.getString(R.styleable.TextView_text);
        mTextSize = typedArray.getDimensionPixelSize(R.styleable.TextView_textSize, mTextSize);
        mTextColor = typedArray.getColor(R.styleable.TextView_textColor, mTextColor);
        typedArray.recycle();
    }

7.完整的代码

package com.nb.customview;

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.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

/**
 * Created by DongKing on 2020/11/5
 * Version 1.0
 * Describe:自定义TextView
 */
class TextView extends View {

    private static final String TAG = "TextView";

    private String mText;
    private int mTextSize = 15;
    private int mTextColor = Color.BLACK;

    private Paint mPaint;

    //    在java 代码中new 的时候使用
    public TextView(Context context) {
        this(context, null);
    }

    //    在layout 中使用
    public TextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    //有style时使用
    public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取xml中设置的属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextView);
        mText = typedArray.getString(R.styleable.TextView_nbText);
        mTextSize = typedArray.getDimensionPixelSize(R.styleable.TextView_nbTextSize, sp2px(mTextSize));
        mTextColor = typedArray.getColor(R.styleable.TextView_nbTextColor, mTextColor);
        typedArray.recycle();

        //初始化画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);

    }

    private int sp2px(int sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
                getResources().getDisplayMetrics());
    }

    /**
     * 指定宽高
     * 针对不同的情况
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        //1.如果指定大小
        int width = MeasureSpec.getSize(widthMeasureSpec);
        //2.wrap_content 计算获取值
        if (widthMode == MeasureSpec.AT_MOST) {
            Rect bounds = new Rect();
            mPaint.getTextBounds(mText, 0, mText.length(), bounds);
            width = bounds.width() + getPaddingLeft() + getPaddingRight();
        }

        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (heightMode == MeasureSpec.AT_MOST) {
            Rect bounds = new Rect();
            mPaint.getTextBounds(mText, 0, mText.length(), bounds);
            height = bounds.height() + getPaddingTop() + getPaddingBottom();
        }
        //设置控件的宽高
        setMeasuredDimension(width, height);

    }

    /**
     * 用于绘制
     *
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
        int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        int baseLine = getHeight() / 2 + dy;

        canvas.drawText(mText, getPaddingLeft(), baseLine, mPaint);
    }

}

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

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        
        <com.nb.customview.TextView
            android:padding="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/purple_200"
            app:nbText="张三"
            app:nbTextColor="@color/teal_200"
            app:nbTextSize="20sp" />

    </LinearLayout>


</LinearLayout>

posted @ 2020-11-06 15:23  Nixon  阅读(114)  评论(0编辑  收藏  举报