以前写过一个基于WheelView的时间选择器(github地址)其实WheelView不仅仅可以用来做时间控件,大家肯定也见过用它做的城市选择控件,身高选择控件等等。先看几个网上找到的图片:
这只是几个控件,图上的每一个可以滑动的Veiw都是一个WheelView,大家完全可以把它当作一个ListView来看。用我们平时写ListView的思维去写它,在配合PopupWindow你会发你能实现各种各样的弹出的滚动控件。现其实其内部也是参考了ListView的源码,相当于重写了一个ListView。
先看一下其基本用法:
xml中:
activity中:
WheelView wl_hour = (WheelView) view.findViewById(R.id.wl_hour);
NumericWheelAdapter numericAdapter1 = new NumericWheelAdapter(this, 0, 23,"%02d");
numericAdapter1.setLabel(" :");
numericAdapter1.setTextSize(20);
wl_hour.setViewAdapter(numericAdapter1);
wl_hour.setCyclic(true);// 可循环滚动
wl_hour.addChangingListener(new OnWheelChangedListener() {
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
}
});
就这么几行代码,一个简单的0到23的滚动控件就实现了,当然我们也可以将它放在PopupWindow中,在屏幕任何地方弹出。
我们看一下WheelView代码的结构:
我们从上往下说先看adapter,其中AbstractWheelAdapter,AbstractWheelTextAdapter,WheelViewAdapter 这三个类是抽象类
和接口定义了一些公用的方法和一些必须实现的。就像我们平时用ListView的adapter时的getCount(),getView() 之类的方法。而我们
最常用到的就是另外两个ArrayWheelAdapter和NumericWheelAdapter了,它俩都是上面抽象类和接口的实现类。理论上讲我们也可以自
己自定义一个实现类,这就不先探讨了。因为上面两个adapter可以实现很多需求了。
先说NumericWheelAdapter。这个主要是处理数字的,当我们传入两个数值,一个开始值和一个结束值,它内部就会帮我们创建结束值
减开始值加1的item。
NumericWheelAdapter numericAdapter1 = new NumericWheelAdapter(this, 0, 23,"%02d");
最后一个值是format格式化。比如我们想让我们的1显示为01 就可以传入上面的格式化String。
再看ArrayWheelAdapter。
public ArrayWheelAdapter(Context context, T items[]) {
super(context);
//setEmptyItemResource(TEXT_VIEW_ITEM_RESOURCE);
this.items = items;
}
这个adapter就跟ListView的adapter一样了,我们可以传入任意类型的数组。
public View getView(int resource, ViewGroup parent) {
switch (resource) {
case NO_RESOURCE:
return null;
case TEXT_VIEW_ITEM_RESOURCE:
TextView textView = new TextView(context);
textView.setPadding(0,20,0,20);
return textView;
default:
return inflater.inflate(resource, parent, false);
}
}
接着看下面的onWheelViewChangedListener,onWheelViewClickedListener,onWheelViewScrollListener 这是三个事件的监听
看名字就知道是滑动完成,点击,和滑动时的监听。我们可以实现来完成我们自己的业务逻辑。
ItemsRange和WheelViewRecycle是两个非常重要的类。ItemsRange是可见的范围,WheelViewRecycle则是保存我们创建出的View
当视图不可见的时候可以重用View增加效率。
WheelScroller内部定义个手势的监听,在WheelView中将时间event传过来,可以处理我们滑动的时的各种状态。
最后就是我们的主View,WheelView了。这就是一个自定义的View啦。大体就是首先将一个LinearLayout布到里面,之后,将adapter中
的itemView获取后放入LinearLayout中。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (viewAdapter != null && viewAdapter.getItemsCount() > 0) {
updateView();//更新视图。重建项目和标签如果有必要,重新计算物品的大小
drawCenterRect(canvas);//为当前值绘制矩形 就是中间的线
drawItems(canvas);// 绘制item
}
if (drawShadows) drawShadows(canvas);//绘制头部和底部的阴影
}
OK结束。用的时候我们可以把它放在activity中也可以放在PopupWindow中在PopupWindow中我们就可以随便怎么弹出啦。