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

来源:互联网 发布:金融大数据平台 编辑:程序博客网 时间:2024/05/20 14:19

(一)概述
上节我们已经学习了完整的自定义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>

运行结果:
这里写图片描述

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

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

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

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

可事实上它是长这样的:
这里写图片描述

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

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

1 0