NumberPickerをカスタマイズして、スタイルと時間の制御を変更します

Androidにはスクロールホイールコントロールを実現できる独自のNumberPickerがあることはわかっていますが、スタイルは固定されており、テキストサイズや色は変更できません。また、プロジェクトはデフォルトのスタイルを必要としないことが多いため、使用量が少なく、オープンソースコントロールがよく使用されます。 WheelViewの実装。実際、自分でスタイルを変更することもできます。この記事では、ほとんどの人のニーズを満たすはずのリフレクションによってスタイルを変更します。

最初の写真:
ここに写真の説明を書いてください

アイデア

NumberPickerのソースコードを読むと、現在表示されている値の描画がforループで実行され、このforループのcanvas.drawText()メソッドが同じPaintオブジェクトを使用していることがわかります。つまり、3つの値は次のようになります。スタイルは一貫しています!

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

したがって、選択した値のスタイルを変更する必要がある場合は、自分でループ用にこれを記述できます。
つまり、onDrawメソッドを書き直します!

  • まず、NumberPickerから継承されたMyNumberPickerクラスを定義します。
  • NumberPickerのonDrawメソッドのコードを直接コピーし、カスタムMyNumberPickerのonDrawメソッドをオーバーライドして、にコードを貼り付けます。super.onDraw()を削除することを忘れないでください!
  • 現時点では、多くの値が定義されていないため、多くのエラーが報告されました。心配しないでください。これらの値はリフレクションを通じて取得できます。

反射を使用して値を取得します

誰もがjavaのリフレクションメカニズムを知っています。クラス名でプロパティとメソッドを取得できます。例えば:

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

さて、値を取得できるようになったので、次の処理は簡単ですが、値が少し取得される可能性があるため、1つずつ取得する必要があります。値を取得したら、forループでやりたいことが何でもできます!好きなだけ大きく塗ることができ、好きな色で塗ることができます!

また、onDraw方式では分割線も描画されるため、分割線の色や高さを数分で簡単に解くことができます。

コードを添付してください:

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

スタイルを数分で決定する場合、次回の時間コントロール、値の選択などは独自のパッケージで完了できます。以前にNumberPickerをカスタマイズしなかったときにカプセル化したコントロールを添付しまし
た。NumberPickerパッケージホイールを使用して時間コントロールを選択します-選択します数値選択文字列

私のgithubにアクセスして、ソースコードを表示およびダウンロードできます。
https://github.com/lizebinbin/PickTimeView
ありがとうスター~~

おすすめ

転載: blog.csdn.net/lizebin_bin/article/details/53582111