Android WheelView 详解

来源:互联网 发布:阿里蒲公英是什么软件 编辑:程序博客网 时间:2024/06/14 12:36

        以前写过一个基于WheelView的时间选择器(github地址)其实WheelView不仅仅可以用来做时间控件,大家肯定也见过用它做的城市选择控件,身高选择控件等等。先看几个网上找到的图片:


 

         这只是几个控件,图上的每一个可以滑动的Veiw都是一个WheelView,大家完全可以把它当作一个ListView来看。用我们平时写ListView的思维去写它,在配合PopupWindow你会发你能实现各种各样的弹出的滚动控件。现其实其内部也是参考了ListView的源码,相当于重写了一个ListView。

        先看一下其基本用法:

xml中:

[html] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. <com.chs.widgets.wheelview.WheelView  
  2.                 android:id="@+id/wl_ymd"  
  3.                 android:layout_width="wrap_content"  
  4.                 android:layout_height="wrap_content"  
  5.                 android:layout_marginRight="15dp"/>  

activity中:
[html] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. WheelView wl_hour = (WheelView) view.findViewById(R.id.wl_hour);  
  2. NumericWheelAdapter numericAdapter1 = new NumericWheelAdapter(this, 0, 23,"%02d");  
  3. numericAdapter1.setLabel("  :");  
  4. numericAdapter1.setTextSize(20);  
  5. wl_hour.setViewAdapter(numericAdapter1);  
  6. wl_hour.setCyclic(true);// 可循环滚动  
  7. wl_hour.addChangingListener(new OnWheelChangedListener() {  
  8.     @Override  
  9.     public void onChanged(WheelView wheel, int oldValue, int newValue) {  
  10.   
  11.   
  12.     }  
  13. });  
就这么几行代码,一个简单的0到23的滚动控件就实现了,当然我们也可以将它放在PopupWindow中,在屏幕任何地方弹出。
我们看一下WheelView代码的结构:
    我们从上往下说先看adapter,其中AbstractWheelAdapter,AbstractWheelTextAdapter,WheelViewAdapter 这三个类是抽象类
和接口定义了一些公用的方法和一些必须实现的。就像我们平时用ListView的adapter时的getCount(),getView() 之类的方法。而我们
最常用到的就是另外两个ArrayWheelAdapter和NumericWheelAdapter了,它俩都是上面抽象类和接口的实现类。理论上讲我们也可以自
己自定义一个实现类,这就不先探讨了。因为上面两个adapter可以实现很多需求了。
    先说NumericWheelAdapter。这个主要是处理数字的,当我们传入两个数值,一个开始值和一个结束值,它内部就会帮我们创建结束值
减开始值加1的item。
[html] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. NumericWheelAdapter numericAdapter1 = new NumericWheelAdapter(this, 0, 23,"%02d");  
最后一个值是format格式化。比如我们想让我们的1显示为01 就可以传入上面的格式化String。
   再看ArrayWheelAdapter。
[html] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. public ArrayWheelAdapter(Context context, T items[]) {  
  2.     super(context);  
  3.       
  4.     //setEmptyItemResource(TEXT_VIEW_ITEM_RESOURCE);  
  5.     this.items = items;  
  6. }  
这个adapter就跟ListView的adapter一样了,我们可以传入任意类型的数组。
[html] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. public View getView(int resource, ViewGroup parent) {  
  2.        switch (resource) {  
  3.        case NO_RESOURCE:  
  4.            return null;  
  5.        case TEXT_VIEW_ITEM_RESOURCE:  
  6.            TextView textView = new TextView(context);  
  7.            textView.setPadding(0,20,0,20);  
  8.            return textView;  
  9.        default:  
  10.            return inflater.inflate(resource, parent, false);      
  11.        }  
  12.    }  

看上面的代码默认的布局是一个TextView我们也可以传入我们自己的布局这样一想是不是可以做各种各样的滚动视图啦。
    
    接着看下面的onWheelViewChangedListener,onWheelViewClickedListener,onWheelViewScrollListener 这是三个事件的监听
看名字就知道是滑动完成,点击,和滑动时的监听。我们可以实现来完成我们自己的业务逻辑。
   
   ItemsRange和WheelViewRecycle是两个非常重要的类。ItemsRange是可见的范围,WheelViewRecycle则是保存我们创建出的View
当视图不可见的时候可以重用View增加效率。
   
    WheelScroller内部定义个手势的监听,在WheelView中将时间event传过来,可以处理我们滑动的时的各种状态。
    
    最后就是我们的主View,WheelView了。这就是一个自定义的View啦。大体就是首先将一个LinearLayout布到里面,之后,将adapter中
的itemView获取后放入LinearLayout中。
    
[html] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.     protected void onDraw(Canvas canvas) {  
  3.         super.onDraw(canvas);  
  4.   
  5.         if (viewAdapter != null && viewAdapter.getItemsCount() > 0) {  
  6.             updateView();//更新视图。重建项目和标签如果有必要,重新计算物品的大小  
  7.   
  8.             drawCenterRect(canvas);//为当前值绘制矩形 就是中间的线  
  9.             drawItems(canvas);// 绘制item  
  10.         }  
  11.   
  12.         if (drawShadows) drawShadows(canvas);//绘制头部和底部的阴影  
  13.     }  
OK结束。用的时候我们可以把它放在activity中也可以放在PopupWindow中在PopupWindow中我们就可以随便怎么弹出啦。
0 0
原创粉丝点击