Personalice NumberPicker para modificar el estilo y el control de tiempo

Sabemos que Android tiene su propio NumberPicker, que puede realizar el control de la rueda de desplazamiento, pero el estilo es fijo y el tamaño o el color del texto no se puede modificar, y a menudo el proyecto no necesita el estilo predeterminado, por lo que se usa menos y los controles de código abierto se usan a menudo. Implementación de WheelView. De hecho, también podemos modificar el estilo por nosotros mismos. En este artículo, modificamos el estilo por reflexión, lo que debe satisfacer las necesidades de la mayoría de las personas.

Primera foto:
Escriba la descripción de la imagen aquí

Ideas

Al leer el código fuente de NumberPicker, puede encontrar que el dibujo del valor mostrado actualmente se realiza en un bucle for, y el método canvas.drawText () en este bucle for utiliza el mismo objeto Paint, lo que significa que los tres valores son ¡El estilo es consistente!

int[] selectorIndices = mSelectorIndices;
for (int i = 0; i < selectorIndices.length; i++) {
    int selectorIndex = selectorIndices[i];
    String scrollSelectorValue = mSelectorIndexToStringCache.get(selectorIndex);
    // Do not draw the middle item if input is visible since the input
    // is shown only if the wheel is static and it covers the middle
    // item. Otherwise, if the user starts editing the text via the
    // IME he may see a dimmed version of the old value intermixed
    // with the new one.
    if ((showSelectorWheel && i != SELECTOR_MIDDLE_ITEM_INDEX) ||
        (i == SELECTOR_MIDDLE_ITEM_INDEX && mInputText.getVisibility() != VISIBLE)) {
         canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
       }
     y += mSelectorElementHeight;
}

Entonces, si necesita cambiar el estilo del valor seleccionado, ¡solo puede escribir esto para el bucle usted mismo!
¡Así que reescribimos el método onDraw !

  • Primero defina la clase MyNumberPicker heredada de NumberPicker.
  • Copie el código en el método onDraw en NumberPicker directamente, anule el método onDraw en el MyNumberPicker personalizado y pegue el código. ¡Recuerde eliminar super.onDraw ()!
  • En este momento, se reportaron muchos errores porque muchos valores no estaban definidos. No se preocupe, ¡podemos obtener estos valores a través de la reflexión!

Usa la reflexión para obtener el valor

Todo el mundo conoce el mecanismo de reflexión de Java. Puede obtener propiedades y métodos por nombre de clase. P.ej:

        //获取全部私有属性
        Field[] pickerFields = NumberPicker.class.getDeclaredFields();
        for (Field field : pickerFields) {
            field.setAccessible(true);
            //遍历找到我们需要获取值的那个属性
            if (field.getName().equals("mSelectorWheelPaint")) {
                try {
                    //获取属性值
                    mSelectorWheelPaint = (Paint) field.get(picker);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;
            }
        }

Bien, ahora que se puede obtener el valor, lo siguiente es fácil de manejar, pero el valor se puede obtener un poco, y es necesario obtenerlo uno por uno. Después de obtener el valor, ¡puede hacer lo que quiera en el ciclo for! ¡Puedes pintar tan grande como quieras y puedes pintar con el color que quieras!

Además, en el método onDraw, también se dibuja la línea divisoria, por lo que el color y la altura de la línea divisoria se resuelven fácilmente en minutos.

Adjunta el código:

 @ Override
protected void onDraw(Canvas canvas) {
    //        super.onDraw(canvas);
    getMyValue();
    mSelectorWheelPaint.setColor(Color.BLUE);

    if (!mHasSelectorWheel) {
        super.onDraw(canvas);
        return;
    }
    final boolean showSelectorWheel = mHideWheelUntilFocused ? hasFocus() : true;
    float x = (mRight - mLeft) / 2;
    float y = mCurrentScrollOffset;
    //这一部分画不画都无所谓!
    //        if (showSelectorWheel && mVirtualButtonPressedDrawable != null
    //                && mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {
    
    
    //            if (mDecrementVirtualButtonPressed) {
    
    
    //                mVirtualButtonPressedDrawable.setState(View.PRESSED_STATE_SET);
    //                mVirtualButtonPressedDrawable.setBounds(0, 0, mRight, mTopSelectionDividerTop);
    //                mVirtualButtonPressedDrawable.draw(canvas);
    //            }
    //            if (mIncrementVirtualButtonPressed) {
    
    
    //                mVirtualButtonPressedDrawable.setState(PRESSED_STATE_SET);
    //                mVirtualButtonPressedDrawable.setBounds(0, mBottomSelectionDividerBottom, mRight,
    //                        mBottom);
    //                mVirtualButtonPressedDrawable.draw(canvas);
    //            }
    //        }

    int[]selectorIndices = mSelectorIndices;
    for (int i = 0; i < selectorIndices.length; i++) {
        int selectorIndex = selectorIndices[i];
        String scrollSelectorValue = mSelectorIndexToStringCache.get(selectorIndex);
        if (i != 1) {
            mSelectorWheelPaint.setColor(Color.BLACK);
            mSelectorWheelPaint.setTextSize(sp2px(16));
        } else {
            mSelectorWheelPaint.setColor(Color.parseColor("#6495ED"));
            mSelectorWheelPaint.setTextSize(sp2px(20));
        }

        if ((showSelectorWheel && i != 1) ||
            (i == 1 && mInputText.getVisibility() != VISIBLE)) {
            Rect mRect = new Rect();
            mSelectorWheelPaint.getTextBounds(scrollSelectorValue, 0, scrollSelectorValue.length(), mRect);
            canvas.drawText(scrollSelectorValue, x, y, mSelectorWheelPaint);
        }
        y += mSelectorElementHeight;
    }

    // draw the selection dividers
    if (showSelectorWheel && mSelectionDivider != null) {
        mSelectionDivider = new ColorDrawable(Color.parseColor("#a0c4c4c4"));
        // draw the top divider
        int topOfTopDivider = mTopSelectionDividerTop;
        int bottomOfTopDivider = topOfTopDivider + 2;
        mSelectionDivider.setBounds(0, topOfTopDivider, mRight, bottomOfTopDivider);
        mSelectionDivider.draw(canvas);

        // draw the bottom divider
        int bottomOfBottomDivider = mBottomSelectionDividerBottom;
        int topOfBottomDivider = bottomOfBottomDivider - 2;
        mSelectionDivider.setBounds(0, topOfBottomDivider, mRight, bottomOfBottomDivider);
        mSelectionDivider.draw(canvas);
    }
}

Si decide el estilo en minutos, los próximos controles de tiempo, selección de valores, etc. se pueden completar a través de su propio paquete, y adjunté los controles que encapsulé cuando no personalicé el NumberPicker antes:
Use la rueda de empaquetado de NumberPicker para seleccionar el control de tiempo-seleccionar Cadena de selección numérica

Puedes ir a mi github para ver y descargar el código fuente:
https://github.com/lizebinbin/PickTimeView
Gracias estrella ~~

Supongo que te gusta

Origin blog.csdn.net/lizebin_bin/article/details/53582111
Recomendado
Clasificación