【Android源码 栏目提醒】:以下是网学会员为您推荐的Android源码 -android仿iPhone滚轮控件实现及源码分析 - 其它资料,希望本篇文章对您学习有所帮助。
android 仿 iPhone 滚轮控件实现及
源码分析(一) 分类:
android 小例子 2012-03-27 14:56 6258 人阅读 评论58 收藏 举报 敬告:由于本文代码较多,所以文章分为了一二两篇,如果不便,敬请谅解,可以先下载文章下方的代码,打开参考本文查看,效果更好!首先,先看下效果图: 这三张图分别是使用滚动控件实现城市,随机数和时间三个简单的例子,当然,界面有点简陋,下面我们就以时间这个为例,开始解析一下。
首先,先看下布局文件:html view plaincopyprint 1.ltxml versionquot1.0quot encodingquotutf-8quotgt 2. 3.ltLinearLayout xmlns:androidquothttp://schemas.
android.com/apk/res/androidquot 4.
android:layout_heightquotwrap_contentquot 5.
android:layout_widthquotfill_parentquot 6.
android:layout_marginTopquot12dpquot 7.
android:orientationquotverticalquot 8.
android:backgroundquotdrawable/layout_bgquotgt 9. 10. ltLinearLayout xmlns:androidquothttp://schemas.
android.com/apk/res/androi dquot 11.
android:layout_heightquotwrap_contentquot 12.
android:layout_widthquotfill_parentquot 13.
android:layout_gravityquotcenter_horizontalquot 14.
android:paddingLeftquot12dpquot 15.
android:paddingRightquot12dpquot 16.
android:paddingTopquot10dpquotgt 17. 18. ltkankan.wheel.widget.WheelView
android:idquotid/hourquot 19.
android:layout_heightquotwrap_contentquot 20.
android:layout_widthquotfill_parentquot 21.
android:layout_weightquot1quot/gt 22. ltkankan.wheel.widget.WheelView
android:idquotid/minsquot 23.
android:layout_heightquotwrap_contentquot 24.
android:layout_widthquotfill_parentquot 25.
android:layout_weightquot1quot/gt 26. lt/LinearLayoutgt 27. 28. ltTimePicker
android:idquotid/timequot 29.
android:layout_marginTopquot12dpquot 30.
android:layout_heightquotwrap_contentquot 31.
android:layout_widthquotfill_parentquot 32.
android:layout_weightquot1quot/gt 33. 34. lt/LinearLayoutgt 里面只有三个控件,两个自定义的 WheelView,还有一个 TimePicker,然后进入代码里面看一下:java view plaincopyprint 1.public class TimeActivity extends Activity 2. // Time changed flag3. private boolean timeChanged false4.5. //6. private boolean timeScrolled false7.8. Override9. public void onCreateBundle savedInstanceState 10. super.onCreatesavedInstanceState11.12. setContentViewR.layout.time_layout13.14. final WheelView hours WheelView findViewByIdR.id.hour15. hours.setAdapternew NumericWheelAdapter0 2316. hours.setLabelquothoursquot17.18. final WheelView mins WheelView findViewByIdR.id.mins19. mins.setAdapternew NumericWheelAdapter0 59 quot02dquot20. mins.setLabelquotminsquot21. mins.setCyclictrue22.23. final TimePicker picker TimePicker findViewByIdR.id.time24. picker.setIs24HourViewtrue25.26. // set current time27. Calendar c Calendar.getInstance28. int curHours c.getCalendar.HOUR_OF_DAY29. int curMinutes c.getCalendar.MINUTE30.31. hours.setCurrentItemcurHours32. mins.setCurrentItemcurMinutes33.34. picker.setCurrentHourcurHours35. picker.setCurrentMinutecurMinutes36.37. // add listeners38. addChangingListenermins quotminquot39. addChangingListenerhours quothourquot40.41. OnWheelChangedListener wheelListener new OnWheelChangedListen er 42. public void onChangedWheelView wheel int oldValue int newValue 43. if timeScrolled 44. timeChanged true45. picker.setCurrentHourhours.getCurrentItem46. picker.setCurrentMinutemins.getCurrentItem47. timeChanged false48. 49. 50. 51.52. hours.addChangingListenerwheelListener53. mins.addChangingListenerwheelListener54.55. OnWheelScrollListener scrollListener new OnWheelScrollListener 56. public void onScrollingStartedWheelView wheel 57. timeScrolled true58. 59. public void onScrollingFinishedWheelView wheel 60. timeScrolled false61. timeChanged true62. picker.setCurrentHourhours.getCurrentItem63. picker.setCurrentMinutemins.getCurrentItem64. timeChanged false65. 66. 67.68. hours.addScrollingListenerscrollListener69. mins.addScrollingListenerscrollListener 70. 71. picker.setOnTimeChangedListenernew TimePicker.OnTimeChangedList ener 72. public void onTimeChangedTimePicker view int hourOfDay int minut e 73. if timeChanged 74. hours.setCurrentItemhourOfDay true 75. mins.setCurrentItemminute true 76. 77. 78. 79. 80. 81. / 82. Adds changing listener for wheel that updates the wheel label 83. param wheel the wheel 84. param label the wheel label 85. / 86. private void addChangingListenerfinal WheelView wheel final String label 87. wheel.addChangingListenernew OnWheelChangedListener 88. public void onChangedWheelView wheel int oldValue int newValue 89. wheel.setLabelnewValue 1 label quotsquot : label 90. 91. 92. 93. 看一下,里面调用 WheelView 的方法有 setAdapter、setLabelquotminsquot、setCyclictrue、setCurrentItem、getCurrentItem、addChangingListener、addScrollingListener这些方法,其中 setAapter 设置数据适配器,setCyclic设置是否是循环,setCurrentItem 和 getCurrentItem 分别是设置现在选择的 item和返回现在选择的 item。
后面两个设置监听的方法中,需要重写两个接口:java view plaincopyprint 1./ 2. Wheel scrolled listener interface. 3. / 4.public interface OnWheelScrollListener 5. / 6. Callback method to be invoked when scrolling started. 7. param wheel the wheel view whose state has changed. 8. / 9. void onScrollingStartedWheelView wheel 10. 11. / 12. Callback method to be invoked when scrolling ended. 13. param wheel the wheel view whose state has changed. 14. / 15. void onScrollingFinishedWheelView wheel 16. 和java view plaincopyprint 1.public interface OnWheelChangedListener 2. / 3. Callback method to be invoked when current item changed 4. param wheel the wheel view whose state has changed 5. param oldValue the old value of current item 6. param newValue the new value of current item 7. / 8. void onChangedWheelView wheel int oldValue int newValue 9.在这里使用的是典型的回调方法模式。
然后现在,我们进入 WheelView 类,看一下他是如何构建,首先,WheelView继承了 View 类。
代码的 22 行到 45 行是导入的所需要的类。
从 54 行到 135 行是声明一些变量和类:java view plaincopyprint 1./ Scrolling duration / 2. private static final int SCROLLING_DURATION 400 3. 4. / Minimum delta for scrolling / 5. private static final int MIN_DELTA_FOR_SCROLLING 1 6. 7. / Current value amp label text color / 8. private static final int VALUE_TEXT_COLOR 0xF0000000 9. 10. / Items text color / 11. private static final int ITEMS_TEXT_COLOR 0xFF000000 12. 13. / Top and bottom shadows colors / 14. private static final int SHADOWS_COLORS new int 0xFF111111 15. 0x00AAAAAA 0x00AAAAAA 16. 17. / Additional items height is added to standard text item height / 18. private static final int ADDITIONAL_ITEM_HEIGHT 15 19. 20. / Text size / 21. private static final int TEXT_SIZE 24 22. 23. / Top and bottom items offset to hide that / 24. private static final int ITEM_OFFSET TEXT_SIZE / 5 25. 26. / Additional width for items layout / 27. private static final int ADDITIONAL_ITEMS_SPACE 10 28. 29. / Label offset / 30. private static final int LABEL_OFFSET 831.32. / Left and right padding value /33. private static final int PADDING 1034.35. / Default count of visible items /36. private static final int DEF_VISIBLE_ITEMS 537.38. // Wheel Values39. private WheelAdapter adapter null40. private int currentItem 041.42. // Widths43. private int itemsWidth 044. private int labelWidth 045.46. // Count of visible items47. private int visibleItems DEF_VISIBLE_ITEMS48.49. // Item height50. private int itemHeight 051.52. // Text paints53. private TextPaint itemsPaint54. private TextPaint valuePaint55.56. // Layouts57. private StaticLayout itemsLayout58. private StaticLayout labelLayout59. private StaticLayout valueLayout60.61. // Label amp background62. private String label63. private Drawable centerDrawable64.65. // Shadows drawables 66. private GradientDrawable topShadow 67. private GradientDrawable bottomShadow 68. 69. // Scrolling 70. private boolean isScrollingPerformed 71. private int scrollingOffset 72. 73. // Scrolling animation 74. private GestureDetector gestureDetector 75. private Scroller scroller 76. private int lastScrollY 77. 78. // Cyclic 79. boolean isCyclic false 80. 81. // Listeners 82. private ListltOnWheelChangedListenergt changingListeners new LinkedLi stltOnWheelChangedListenergt 83. private ListltOnWheelScrollListenergt scrollingListeners new LinkedListltO nWheelScrollListenergt 在这里面,使用到了 StaticLayout,在开发文档中找一下这个类:plain view plaincopyprint 1.StaticLayout is a Layout for text that will not be edited after it is laid out. Use Dy namicLayout for text that may change. 2. 3.This is used by widgets to control text layout. You should not need to use this cl ass directly unless you are implementing your own widget or custom display o bject or would be tempted to call Canvas.drawText directly.staticLayout 被创建以后就不能被修改了,通常被用于控制文本组件布局。
还使用到了 Drawable、TextPaint、GradientDrawable、GestureDetector、Scroller 类,在开发文档中,GradientDrawable 的概述:plain view plaincopyprint 1.A Drawable with a color gradient for buttons backgrounds etc. 2. 3.It can be defined in an XML file with the ltshapegt element. For more information see the guide to Drawable Resources.就是说这个类可以为按钮或者背景等提供渐变颜色的绘制。
TextPaint 的概述:plain view plaincopyprint 1.TextPaint is an extension of Paint that leaves room for some extra data used du ring text measuring and drawing. TextPaint 是 Paint 类的一个扩展,主要是用于文本在绘制的过程中为附件的数据留出空间。
GestureDetector:手势检测,看下开发文档中关于该类的概述:plain view plaincopyprint 1.Detects various gestures and events using the supplied MotionEvents. The Gest ureDetector.OnGestureListener callback will notify users when a particular mo tion event has occurred. This class should only be used with MotionEvents rep orted via touch dont use for trackball events. 为各种手势和事件提供 MotionEvents。
当一个具体的事件发生时会调用回调函数GestureDetector.OnGestureListener。
这个类应该只适用于 MotionEvents 通过触摸触发的事件不要使用追踪事件。
140 行到 156 行是构造方法, 在 175 到 183 行是 set 和 getAdapter。
193行,setInterpolator方法,设置 interPolator 这个动画接口,我们看下这个接口的概述:plain view plaincopyprint 1.An interpolator defines the rate of change of an animation. This allows the basic animation effects alpha scale translate rotate to be accelerated decelerate d repeated etc.定义了一种基于变率的一个动画。
这使得基本的动画效果alpha scale translate rotate是加速减慢重复等。
这个方法在随机数这个例子中被使用。
203 行到 213 行设置显示的 item 条数。
在 setVisibleItems方法里面调用了 View 的 invalidate方法,看下文档中对该方法的介绍:plain view plaincopyprint 1.Invalidate the whole view. If the view is visible onDrawandroid.graphics.Canva s will be called at some point in the future. This must be called from a UI thre ad. To call from a non-UI thread call postInvalidate.使全部视图失效,如果 View 视图是可见的,会在 UI 线程里面从新调用 onDraw方法。
223 行到 233 行是设置 Label,既后面图片中的 hours. 245 行到 296 行是设置监听,在上面已经简单的说了一下,这里不在累述。
就是在那个阴影条框下的那个部分, 307 行到 349 行是设置正被选中 item,比较简单。
里面主要调用了 scroll 这个方法:java view plaincopyprint 1./ 2. Scroll the wheel 3. param itemsToSkip items to scroll 4. param time scrolling duration 5. / 6. public void scrollint itemsToScroll int time 7. scroller.forceFinishedtrue 8. lastScrollY scrollingOffset 9. int offset itemsToScroll getItemHeight 10. scroller.startScroll0 lastScrollY 0 offset - lastScrollY time 11. setNextMessageMESSAGE_SCROLL 12. startScrolling 13. 357 行到 365 行是设置 item 数据能否循环使用。
384 行的 initResourcesIfNecessary方法,从字面意思,如果需要的初始化资源。
java view plaincopyprint 1.private void initResourcesIfNecessary 2. if itemsPaint null 3. itemsPaint new TextPaintPaint.ANTI_ALIAS_FLAG 4. Paint.FAKE_BOLD_TEXT_FLAG 5. //itemsPaint.density getResources.getDisplayMetrics.density 6. itemsPaint.setTextSizeTEXT_SIZE 7. 8. 9. if valuePaint null 10. valuePaint new TextPaintPaint.ANTI_ALIAS_FLAG 11. Paint.FAKE_BOLD_TEXT_FLAG Paint.DITHER_FLAG 12. //valuePaint.density getResources.getDisplayMetrics.density 13. valuePaint.setTextSizeTEXT_SIZE 14. valuePaint.setShadowLayer0.1f 0 0.1f 0xFFC0C0C0 15. 16. 17. if centerDrawable null 18. centerDrawable getContext.getResources.getDrawableR.drawab le.wheel_val 19. 20. 21. if topShadow null 22. topShadow new GradientDrawableOrientation.TOP_BOTTOM SHA DOWS_COLORS 23. 24. 25. if bottomShadow null 26. bott.
上一篇:
Linux系统下的Android开发环境搭建
下一篇:
7*30m公路预应力混凝土连续梁桥上部结构设计