Controles personalizados de Android (1) --- artículos básicos

Cuando se trata de controles personalizados de Android, esta es un área deseada y aterradora, y es la única forma de ser un desarrollador de Android.

También soy un principiante, con un corazón para compartir, comparto los puntos de conocimiento que entiendo con ustedes y espero corregir las deficiencias.

Jajaja, he hablado demasiado, ¡vayamos al punto de abajo!

1. Conocimientos preliminares de los controles personalizados

① Método de construcción

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

El sistema nos proporciona cuatro métodos de construcción, sin embargo, el cuarto apenas se utiliza y todos están listados.

Para los tres métodos de construcción anteriores, lo que necesitamos dominar es: ①Cuando se llaman estos métodos de construcción, como con la detección del ciclo de vida de la actividad, se puede distinguir imprimiendo el registro (el período de llamada se ha anotado en el lateral, con suerte)

                                                                             Por lo general, modificamos el super de los dos primeros métodos de construcción para facilitar el procesamiento unificado en el tercer método de construcción.

② Métodos comunes

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

    }
}

 Para el método onMeasure (), necesitamos aclarar los siguientes puntos:

         El primer punto: widthMeasureSpec, heightMeasureSpec son valores binarios de 32 bits. Los dos primeros dígitos representan el modo que se puede obtener a través de MeasureSpec.getMode, y los últimos 30 dígitos representan el ancho y alto máximos que se pueden obtener a través de MeasureSpec.getSize

         El segundo punto: MeasureSpec.makeMeasureSpec () Este método se puede utilizar para establecer el modo de medición (este lugar implicará una pregunta de entrevista = "S ListView anidado ListView de rollView no se muestra completamente, que se explicará en capítulos posteriores)

         El tercer punto: setMeasuredDimension () Este método se puede utilizar para establecer el ancho y el alto de un control personalizado

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

 Para el  método onDraw (), es casi suficiente dominar lo anterior, y lo explicaremos en detalle cuando lo usemos más adelante.

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

 Para el  método onTouchEvent (), no se puede decir con una palabra, también tiene que reflejar su valor en el combate real.

Al ver esto, significa que ha dominado los conceptos básicos, ¿no cree que es muy simple? ! ! , Jajaja. Pero no subestimes al enemigo, fácil en el frente significa amargura en la espalda

Supongo que te gusta

Origin blog.csdn.net/qq_41885673/article/details/113995362
Recomendado
Clasificación