四种常用的标准自定义View方法(下)

(一)概述
上节我们已经学习了完整的自定义View以及ViewGroup的详细流程和注意事项,今天我们学习——-继承自特定的View和ViewGroup

(二)继承自特定的View

继承我们最为熟悉的TextView ,我们不需要自己处理onMeasure()跟onLayot()方法,我们先来引用下徐大神的自定义TextView , 非常简约的自定义TextView ,我们一点点抽丝剥茧来看,把它改造成一个完美+标准的自定义TextView;
源码如下:

MyTextView.java

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;

public class MyTextView extends TextView {

    private Paint mPaint1, mPaint2;

    public MyTextView(Context context) {
        super(context);
        initView();
    }

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

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

    private void initView() {
        mPaint1 = new Paint();
        mPaint1.setColor(getResources().getColor(
                android.R.color.holo_blue_light));
        mPaint1.setStyle(Paint.Style.FILL);
        mPaint2 = new Paint();
        mPaint2.setColor(Color.YELLOW);
        mPaint2.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 绘制外层矩形
        canvas.drawRect(
                0,
                0,
                getMeasuredWidth(),
                getMeasuredHeight(),
                mPaint1);
        // 绘制内层矩形
        canvas.drawRect(
                10,
                10,
                getMeasuredWidth() - 10,
                getMeasuredHeight() - 10,
                mPaint2);
        canvas.save();
        // 绘制文字前平移10像素
        canvas.translate(10, 0);
        // 父类完成的方法,即绘制文本
        super.onDraw(canvas);
        canvas.restore();
    }
}

代码比较简单,简单说下:
初始化完成以后没执行onDraw()方法,这里TextView的OnDraw()方法的作用是绘制TextView的文本信息内容的,通过使用super来调用父类的OnDraw()方法,那么问题来了,我想给这个文本做一个矩形相框,怎么搞?必然是先把相框做好了,然后把文本弄上去,这就回答了,为什么要在super之前绘制矩形了!代码逻辑就是这样的;

activity_main.xml文件如下:

<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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.mycoustomtextview.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:text="因崔思婷~"
        android:textSize="30sp"/>

LinearLayout>

运行结果:
四种常用的标准自定义View方法(下)_第1张图片

细心的小伙伴们,大概发现了对吧~没错,这货的宽高居然都是wrap_content ?按照我们之前说的,它没有从写OnMeasure()方法呀!显示效果应该是跟math_parent完全的一样的呀(即铺满屏幕),这是为什么呢?自然是去看看TextView的源码了:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        throw new RuntimeException("Stub!");
    }

哇哈哈~它并没有进行“测量模式+测量大小”的套路,而是直接得到了测量值得,那么它是否支持padding 跟margin ?当然了!你可以试试~

好了,我们继续~这里允许我吐槽一下Android 的原生控件,比如SearchView ,我理想的SearchView是这样的:
这里写图片描述

可事实上它是长这样的:
四种常用的标准自定义View方法(下)_第2张图片

怎么样是不是感觉丑哭了,o(╯□╰)o !!!
所以,我们需要在原生控件的基础上加入自己的自定义属性,那SearchView来说,我们增加了最右边的删除”X”,最左边的搜索图标,外围加入了一个矩形等自定义属性,看起来漂亮多了,别急,我后面会写一个加入TextView属性的自定义RelativeLayout;

(三)继承特定的ViewGroup
自定义ViewGroup跟继承特定ViewGroup方法步骤类似,只是自定义ViewGroup更加贴近底层,那么什么候会使用这个方法,当某种效果看起来像多个View组合而成的时候可以使用;(暂时还没有找到一个恰当的案例,找到了我一定给大家补上)

你可能感兴趣的:(Android学习笔记之进阶篇,继承,view,Group,特定)