Android自定义控件(一)---基础篇

谈到 Android自定义控件 ,这是一个令人渴望又害怕的领域,是作为一个Android开发人员的必经之路。

鄙人也是一名初学者,怀着一颗分享的心,将自己所理解的知识点与君分享,不足之处望纠正

哈哈哈,说的有点多了,下面直入正题吧!

一、自定义控件预备知识点

①构造方法

package com.example.mytextview;

//import javax.swing.text.View;  这里别到错了包,这个包是错误的 
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;        //这个是正确的包

import androidx.annotation.Nullable;

ppublic class TextView extends View {
    // 构造函数会在代码里面new的时候调用 : TextView tv = new TextView(this);
    // 用 this 的好处就是 不管你从哪个构造函数 进入, 都会走到第三个里面 进行统一处理
    public TextView(Context context) {
        this(context,null);
    }

    // 在布局 layout 中使用(调用) :
    // <com.example.view_day01.TextView
    // android:layout_width="wrap_content"
    // android:layout_height="wrap_content"
    // android:text="Hello World!" />
    public TextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    // 在布局 layout 中使用(调用) 但是会有style:
    // <com.example.view_day01.TextView
    //  style="@style/myStyle"
    // android:text="Hello World!" />
    public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

系统为我们提供了 四种构造方法 但是,第四种几乎用不到,所有,为列出。

对于以上三种构造方法,我们需要掌握的就是:①这几个构造方法在什么时候被调用,和Activity生命周期检测一样,可以通过打印Log来分辨,(调用时期已注解在旁边,望知)

                                                                             ②我们通常将前两个构造方法的 super 修改为 this,方便在第三个构造方法里进行统一处理。

②常用方法

onMeasure

/**
*自定义View的测量方法
*@Author yiqi
*@created 2021/2/22 14:04
*@param widthMeasureSpec || heightMeasureSpec 32位的值  前两位是 model :MeasureSpec.AT_MOST
 *                        后三十位是 Integer.MAX_VALUE
*@return
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    //这个可以解决 ScrollView 嵌套 ListView 显示不全的问题(面试常被问及)
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2 , MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    //布局的宽高都是由这个方法指定
    //指定控件的宽高,需要测量
    //获取宽高的模式
    int widthMode = MeasureSpec.getMode(widthMeasureSpec); //获取前两位
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    //获取宽高的值
    int widthSize = MeasureSpec.getSize(widthMeasureSpec); //获取后面30位
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    // MeasureSpec.AT_MOST : 在布局中指定了wrap_content
    // MeasureSpec.EXACTLY : 在布局中指定了确切的值 100dp match_parent fill_parent
    // MeasureSpec.UNSPECIFIED : 尽可能的大 , 很少能用到 ListView ScrollView 在测量子布局的时候会用到 UNSPECIFIED
    if (widthMode == MeasureSpec.UNSPECIFIED){

    }
}

 对于onMeasure()这个方法,我们需要弄清楚一下几点:

         第一点:widthMeasureSpec, heightMeasureSpec 都是 32位二进制值,前两位代表模式 可以通过 MeasureSpec.getMode 获取,后30位代表最大宽高 可以通过 MeasureSpec.getSize 获取

         第二点:MeasureSpec.makeMeasureSpec() 这个方法可以用来设置 测量模式,(这个地方会牵扯一个面试问题=》S从rollView里嵌套ListView ListView显示不全问题,后面章节进行讲解)

         第三点:setMeasuredDimension()  这个方法可以用来设置自定义控件的宽高

onDraw

/**
*用于绘制
*@Author yiqi 
*@created 2021/2/22 18:00
*@param 
*@return 
*/
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //画文本
    canvas.drawText();
    //画弧
    canvas.drawArc();
    //画圆
    canvas.drawCircle();
}

 对于 onDraw() 方法 主要是掌握以上就差不多了,后面用到时会详细讲解

onTouchEvent

/**
*处理跟用户交互的 手指触摸等等
*@Author yiqi
*@created 2021/2/22 18:05
*@param
*@return
*/
@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);
}

 对于 onTouchEvent() 方法,并非一言两语就能说尽的,它也是得在实战中体现其价值。

看到这里,就说明你掌握基础了,是不是觉得很简单呢!!!,哈哈哈。可是别轻敌,前面轻松代表后面很苦哦

猜你喜欢

转载自blog.csdn.net/qq_41885673/article/details/113995362
今日推荐