Android custom controls (1) --- basic articles

When it comes to Android custom controls, this is an area that is eager and scary, and it is the only way to be an Android developer.

I am also a beginner, with a heart of sharing, I share the knowledge points I understand with you, and I hope to correct the deficiencies.

Hahaha, I've talked a little too much, let's get to the point below!

1. Preliminary knowledge of custom controls

① Construction method

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);
    }
}

The system provides us with four construction methods. However, the fourth one is hardly used, and all of them are listed.

For the above three construction methods, what we need to master is: ①When these construction methods are called, as with Activity life cycle detection, it can be distinguished by printing Log. (The calling period has been annotated on the side, hopefully)

                                                                             ②We usually modify the super of the first two construction methods to this to facilitate unified processing in the third construction method.

② Common methods

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){

    }
}

 For the onMeasure () method, we need to clarify the following points:

         The first point: widthMeasureSpec, heightMeasureSpec are both 32-bit binary values. The first two digits represent the mode can be obtained through MeasureSpec.getMode, and the last 30 digits represent the maximum width and height can be obtained through MeasureSpec.getSize

         The second point: MeasureSpec.makeMeasureSpec() This method can be used to set the measurement mode (this place will involve an interview question = "S nested ListView ListView from rollView is not fully displayed, which will be explained in the following chapters)

         The third point: setMeasuredDimension() This method can be used to set the width and height of a custom control

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();
}

 For the  onDraw () method, it’s almost enough to master the above, and we will explain it in detail when we use it later.

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);
}

 For the  onTouchEvent () method, it cannot be said in a word, it also has to reflect its value in actual combat.

Seeing this, it means that you have mastered the basics, don't you think it's very simple! ! ! , Hahaha. But don’t underestimate the enemy, easy in the front means bitterness in the back

Guess you like

Origin blog.csdn.net/qq_41885673/article/details/113995362