Personalize NumberPicker para modificar o estilo e o controle de tempo

Sabemos que o Android tem seu próprio NumberPicker, que pode realizar o controle da roda de rolagem, mas o estilo é fixo e o tamanho ou a cor do texto não podem ser modificados e, muitas vezes, o projeto não precisa do estilo padrão, por isso é menos usado e os controles de código aberto costumam ser usados Implementação do WheelView. Na verdade, também podemos modificar o estilo por nós mesmos.Neste artigo, modificamos o estilo por reflexão, que deve atender às necessidades da maioria das pessoas.

Primeira foto:
Escreva a descrição da imagem aqui

Ideias

Lendo o código-fonte do NumberPicker, você pode descobrir que o desenho do valor exibido atualmente é executado em um loop for, e o método canvas.drawText () neste loop for usa o mesmo objeto Paint, o que significa que os três valores são O estilo é 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;
}

Portanto, se você precisar alterar o estilo do valor selecionado, só poderá escrever isso para o loop você mesmo!
Então, reescrevemos o método onDraw !

  • Primeiro defina a classe MyNumberPicker herdada de NumberPicker.
  • Copie o código no método onDraw no NumberPicker diretamente, substitua o método onDraw no MyNumberPicker personalizado e cole o código. Lembre-se de excluir super.onDraw ()!
  • Neste momento, muitos erros foram relatados porque muitos valores não foram definidos. Não se preocupe, podemos obter esses valores através da reflexão!

Use reflexão para obter o valor

Todo mundo conhece o mecanismo de reflexão de java.Você pode obter propriedades e métodos por nome de classe. Por exemplo:

        //获取全部私有属性
        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;
            }
        }

Ok, agora que o valor pode ser obtido, a próxima coisa é fácil de manipular, mas o valor pode ser obtido um pouco, e você precisa obtê-lo um por um. Depois de obter o valor, você pode fazer o que quiser no loop for! Você pode pintar do tamanho que quiser e com a cor que quiser!

Além disso, no método onDraw, a linha divisória também é desenhada, de forma que a cor e a altura da linha divisória são facilmente resolvidas em minutos.

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

Se você decidir o estilo em minutos, os controles da próxima vez, seleção de valores, etc. podem ser concluídos por meio de sua própria embalagem, e anexei os controles que encapsulei quando não personalizei o NumberPicker antes:
Use a roda de embalagem NumberPicker para selecionar o controle de tempo String de seleção numérica

Você pode acessar meu github para visualizar e baixar o código-fonte:
https://github.com/lizebinbin/PickTimeView
Obrigado, estrela ~~

Acho que você gosta

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