自定义NumberPicker修改样式、时间控件

我们知道Android有自带的NumberPicker,可以实现滚轮控件,但是样式是固定的,不能修改文字大小或者颜色等,而往往项目中需要的不是默认的样式,所以使用得就比较少,往往使用开源控件WheelView实现。其实,我们也可以自己修改样式的,本文中就是通过反射的方式修改样式,应该可以满足大部分人的需求了。

先上图:
这里写图片描述

思路

阅读NumberPicker的源码可以发现,当前显示的值的绘制是在一个for循环中进行的,而这个for循环中的canvas.drawText()方法使用的是同一个Paint对象,也就是说这三个值的样式是一致的!

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

那么如果需要改变选中的值的样式的话,只能自己写这个for循环!
所以—我们重写onDraw方法!

  • 首先定义MyNumberPicker类继承自NumberPicker。
  • 直接把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;
            }
        }

ok,既然能获取到值了,那么接下来的事情就很好办了,只是可能获取的值会有点多,需要自己一个一个去获取。获取到值后,就可以在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
谢谢您的star~~

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
u-picker 是基于 Vue.js 的时间选择器组件,可以用于选择日期、时间、日期时间等。下面是一个简单的示例: ```html <template> <div> <u-picker v-model="value" type="datetime" :min-date="minDate" :max-date="maxDate" :date-formatter="formatter" :columns-order="columnsOrder" /> </div> </template> <script> import { UPicker } from 'vue-awesome/components' import 'vue-awesome/icons/calendar' import 'vue-awesome/icons/clock' export default { components: { UPicker }, data() { return { value: new Date(), minDate: new Date(2010, 0, 1), maxDate: new Date(2030, 11, 31), columnsOrder: ['year', 'month', 'date', 'hour', 'minute'], } }, methods: { formatter(type, value) { if (type === 'year') { return value + '年' } else if (type === 'month') { return value + '月' } else if (type === 'date') { return value + '日' } else if (type === 'hour') { return value + '时' } else if (type === 'minute') { return value + '分' } return value }, }, } </script> ``` 在上面的代码中,我们使用了 `u-picker` 组件,并绑定了 `value` 属性来实现时间选择器的双向绑定。通过设置 `type` 属性来指定时间选择器的类型,可以选择日期、时间、日期时间等。`min-date` 和 `max-date` 属性用于设置可选范围,`date-formatter` 属性用于自定义每个列的显示格式,`columns-order` 属性用于设置列的显示顺序。 除了以上示例中的基本用法,u-picker 还提供了许多其它的配置选项,可根据需求进行相应的设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值