您的位置:首页 > Web前端 > CSS

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

2016-12-12 14:06 656 查看
我们知道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~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐