自定义NumberPicker修改样式、时间控件
2016-12-12 14:06
656 查看
我们知道Android有自带的NumberPicker,可以实现滚轮控件,但是样式是固定的,不能修改文字大小或者颜色等,而往往项目中需要的不是默认的样式,所以使用得就比较少,往往使用开源控件WheelView实现。其实,我们也可以自己修改样式的,本文中就是通过反射的方式修改样式,应该可以满足大部分人的需求了。
先上图:
那么如果需要改变选中的值的样式的话,只能自己写这个for循环!
所以—我们重写onDraw方法!
首先定义MyNumberPicker类继承自NumberPicker。
直接把NumberPicker中onDraw方法中的代码复制过来,在自定义的MyNumberPicker中重写onDraw方法,把代码粘贴进去。记得把super.onDraw()删掉!
这时候发现报一大堆的错,是因为一堆的值没有定义,不要急,这些值我们可以通过反射来获取!
ok,既然能获取到值了,那么接下来的事情就很好办了,只是可能获取的值会有点多,需要自己一个一个去获取。获取到值后,就可以在for循环中为所欲为啦!想绘制多大就多大,想绘制什么颜色就什么颜色!
另外,在onDraw方法中,也绘制了分割线,所以分割线的颜色和高度也是分分钟轻松搞定了啊
附上代码:
分分钟搞定了样式是不是,接下来的时间控件、选择数值等就通过自己的封装就能完成了,附上我之前没有自定义NumberPicker的时候封装的控件:
使用NumberPicker封装滚轮选择时间控件-选择数值-选择字符串
可前往我的github查看与下载源码哦:
https://github.com/lizebinbin/PickTimeView
谢谢您的star~~
先上图:
思路
阅读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~~
相关文章推荐
- 从零开始学_JavaScript_系列(九)——dojo(2)(AJAX、时间控件、鼠标事件、样式修改、事件移除、消息发布订阅)
- android自定义时间控件NumberPicker
- 仿iOS的Pi 4000 ckerView控件,有时间选择和选项选择,并支持一二三级联动,支持自定义样式
- GridView控件实现自定义数字、时间、货币字符串格式
- wpf日历控件制作过程分析(2)---自定义样式属性
- 扩展GridView控件(10) - 自定义分页样式
- 自定义MembershipProvider来利用Asp.net 2.0 Login控件的登陆和修改密码模块
- ASP.NET: 为自定义控件设置主题(Theme)样式
- 稳扎稳打Silverlight(40) - 3.0绑定之Element to Element Binding, RelativeSource; 样式之动态修改样式, 样式继承, 自定义光标
- 开发自定义的控件样式
- wpf日历控件制作过程分析(2)---自定义样式属性
- Flex中如何用backgroundDisabledColor样式,自定义TextInput控件在无效状态下填充颜色
- 最简单的方法在DataGrid中自定义样式列(通过继承可以在Datagrid中使用下拉列表框,日期控件等)
- 扩展GridView控件(10) - 自定义分页样式
- Flex中自定义Alert控件按钮(Button)样式的例子
- 超菜也玩CS(四):修改CommunityServer分页控件的样式
- 修改上传文件控件样式并实现上传文件功能
- 修改自定义WEB控件的前缀
- js时间控件(精确到时分秒)--具有选择修改的功能
- Axure RP Pro - 相关问题 - 修改自定义样式对已应用该样式部件的逻辑