Acerca del uso del selector de color de Android (1)

El contenido de este artículo es desarrollar un selector de color de 0-1, primero las representaciones
representaciones

Los archivos de código fuente relevantes se adjuntarán al final del artículo.

El efecto se muestra en la figura. Este artículo describirá cómo personalizar dicho control. El código se encuentra al final del artículo.

pensar

(1) Método de implementación
(2) Formato de datos pasado a la capa empresarial
(3) Detalles de implementación

Es necesario que pensemos en los tres puntos anteriores.
(1), se recomienda que el método de implementación elegido aquí sea la vista personalizada, porque este tipo de diseño no es compatible con los controles ordinarios.
(2) Para la capa empresarial, lo que se debe hacer es pasar los datos de color a nuestro control, y luego, después de que el control seleccione el color, los datos de color se devuelven intactos a la capa empresarial. Aquí, el formato de cadena se selecciona como el valor del color Pase, como "#ffffff".
(3) En la implementación, vale la pena pensar en cómo dibujar arcos correctamente usando el lienzo, cómo calcular ángulos reales, conversión de datos de intervalos de cuadrantes, conversión de datos de coordenadas y cálculo de coordenadas de eventos de clic.

Bien, después de pensarlo, empieza a trabajar.

Proceso de implementación

##### (1) Definición de clases
Para crear controles similares, es necesario tener un esquema de pensamiento, es decir, qué métodos expone mi biblioteca de controles al mundo exterior y cómo necesito procesar los datos entrantes desde el exterior internamente. Por lo tanto, primero debes definir el método abstracto:

(1) Clase abstracta de control:

 interface LibColorCirclePickerApi {

    fun setColor(color: Array<Array<String>>)

    fun setLibColorCirclePickerListener(listener: LibColorCirclePickerListener)

    fun removeLibColorCirclePickerListener()
}

(2) Clase de monitoreo externo:

interface LibColorCirclePickerListener {

    fun selInfo(info: LibColorSelInfo)

}

Una vez definidos estos métodos, se pueden implementar mediante herencia.

#####(2) Personalizar la vista para obtener el valor del color del dibujo

Esto implica conocimiento del dibujo en lienzo, compréndalo de antemano.
Como se muestra en la figura, el dibujo se divide en dos niveles. Uno es el círculo central y el otro es el bloque de color.

Antes de dibujar, es necesario determinar las siguientes variables para facilitar el dibujo posterior:
(1) El punto de coordenadas central del dibujo, punto x, y. Aquí tome x/2, y/2.
(2) Radio de dibujo, aquí el lado más corto se utiliza generalmente como radio de dibujo.
(3) Dibuje el radio del círculo central y multiplíquelo con (2) por una determinada proporción para obtener el radio del círculo central.
(4) Excepto por el círculo central, la longitud del radio restante se dividirá uniformemente y se calculará la longitud del radio de cada capa de bloques de color.
(5) Inicializar valores de variables intermedias relacionadas (como el conjunto de coordenadas del bloque de color)

Después de inicializar las variables relevantes, comience a dibujar:

dibujar el círculo central

Para el círculo central, simplemente llame directamente al método de dibujo del círculo del lienzo, sin más detalles.

dibujar bloques de colores

Para los bloques de color, primero debe determinar cuántas capas tiene su bloque de color, lo que determina la longitud del radio de cada capa de bloques de color. El número de capas aquí está determinado por la matriz bidimensional pasada desde el exterior. Para la matriz bidimensional entrante, una dimensión determina el nivel y las dos dimensiones son la matriz de bloques de colores bajo una dimensión.

Según la comprensión anterior, la "longitud del radio de cada capa de bloques de color" se puede obtener dividiendo el "radio restante" por el "número de capas de bloques de color".

Luego divida 360 por el "número de bloques de color por capa" para obtener el ángulo que ocupa cada bloque de color.

Finalmente, configurando el ancho del trazo del pincel, puedes dibujar.

Finalmente, el "valor de rango de radio", el "valor de rango de ángulo" y el "valor de color" generados durante el proceso de dibujo se guardan a través de variables intermedias para llamadas de eventos táctiles posteriores.

PD:

Aquí hay un detalle de implementación, que trata sobre el ancho del trazo de Paint. En realidad, se basa en la expansión de ambos extremos de las coordenadas del dibujo. Por ejemplo, si dibuja una línea recta, se expandirá en ambos extremos de la coordenada Y, como (x, y) (0,10), y el ancho del trazo es 10, entonces el ancho del lado en ángulo recto será basado en (0,5)-(0,15) medio.

Por lo tanto, después de configurar el ancho del trazo y dibujar, debe reservar la posición en la implementación del dibujo.

evento táctil

Para los eventos táctiles, deben procesarse en onTouchEvent. El método de la clase principal es el siguiente:

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {

            }
            MotionEvent.ACTION_MOVE -> {

            }
            MotionEvent.ACTION_UP -> {
                val currentX = event.x
                val currentY = event.y
                dealWithUpEvent(currentX, currentY)
            }
            MotionEvent.ACTION_CANCEL -> {

            }
        }
        return true
    }

Aquí, al devolver verdadero, esta vista intercepta y procesa todos los eventos.

Imagina que tienes las coordenadas del centro y las coordenadas x, y cuando haces clic. ¿Es posible derivar una lógica de "intervalo de cuadrante"? Luego, mediante el método de la fórmula matemática tan, se puede obtener el ángulo correspondiente.

Ahora que tenemos el ángulo y el cuadrante, podemos calcular el ángulo de clic real final y el radio del punto de coordenadas de clic. El código central es el siguiente:

    /**
     * 处理手势抬起事件
     * */
    private fun dealWithUpEvent(currentX: Float, currentY: Float) {
        //判断象限
        val trainX = (currentX - mCenterX)
        val trainY = (mCenterY - currentY)

        //求半径长度
        val x = abs(abs(currentX) - abs(mCenterX)).toDouble()
        val y = abs(abs(mCenterY) - abs(currentY)).toDouble()
        //半径
        val trainRadius = sqrt((x.pow(2.0) + y.pow(2.0)))
        //角度
        val angle = atan(abs(x) / abs(y)) * 180 / PI
        //计算后,再根据象限,转换最终的角度
        var trainAngle = 0f
        if (trainX <= 0 && trainY >= 0) {
            trainAngle = (90 - angle + 270).toFloat()
        } else if (trainX >= 0 && trainY >= 0) {
            trainAngle = angle.toFloat()
        } else if (trainX <= 0 && trainY <= 0) {
            trainAngle = (angle + 180).toFloat()
        } else if (trainX >= 0 && trainY <= 0) {
            trainAngle = (90 - angle + 90).toFloat()
        } else {
            return
        }
//        Log.d("dealWithUpEvent", "angle $angle + 转换角度  $trainAngle 半径: $trainRadius")
        //通过象限,角度,半径,三个条件,确定具体的位置
        val filterList: MutableList<LibColorInnerPosInfo> = ArrayList()
        this.mColorPosInfo.filter {
            it.startAngle <= trainAngle && it.endAngle >= trainAngle
        }.filter {
            it.startRadius >= trainRadius && it.endRadius <= trainRadius
        }.filter {
            !it.color.isNullOrBlank()
        }.toCollection(filterList)

        if (filterList.size != 1) {
            return
        }
        mListener?.selInfo(LibColorSelInfo().apply {
            this.colorStr = filterList.first().color
        })
    }

En este punto, se ha explicado todo el proceso. Si aún hay algo que no comprende, descargue el código fuente para comprenderlo:

Código de extracción del código fuente
: naf2

eso es todo------------------------------------------------ --------------

Supongo que te gusta

Origin blog.csdn.net/motosheep/article/details/129680892
Recomendado
Clasificación