Android时间滚轮(二)

本篇文章标题虽然是Android时间滚轮(二),但是其内容却是讲述的是自定义滚轮控件而时间选择器只是其中的一部分而已。废话不多说,先上效果果图。

一、效果图

1.1地址的效果图,支持三级联动


Android时间滚轮(二)_第1张图片


1.2 时间的效果图

Android时间滚轮(二)_第2张图片

1.3 自定义数据的效果图,支持单击条目获取对应条目的数据

Android时间滚轮(二)_第3张图片

二、代码实现

从上面的效果图可以看到布局很简单,所以在这里就不展示关于布局文件的代码了。
2.1 地址对话框三级联动的核心代码

public void onChanged(WheelView wheel, int oldValue, int newValue) {
        if (wheel == mViewProvince) {
            updateCities();  //更新城市
        } else if (wheel == mViewCity) {
            updateAreas();  //更新地区
        } else if (wheel == mViewDistrict) {  //更新编码
            mCurrentDistrictName = mDistrictDatasMap.get(mCurrentCityName)[newValue];
            tmp3 = newValue;
            mCurrentZipCode = mZipcodeDatasMap.get(mCurrentDistrictName);
        }
    }

2.2 时间对话框的更新核心代码

@Override
    public void onChanged(WheelView wheel, int oldValue, int newValue) {
        if (wheel == year || wheel == month) {
            int yearNum = year.getCurrentItem() + START_YEAR;
            int monthNum = month.getCurrentItem() + 1;
            //如果当期滑动的是年并且当前月份不等于2时结束监听避免重复创建对象
            if (wheel == year && monthNum != 2) { 
                return;
            }
            initDay(yearNum, monthNum, context);
        }
    }

2.3 数据对话框单击条目的核心代码

 public void onItemClicked(WheelView wheel, int itemIndex) {
        selectAdd.selectedResult(mDatas[itemIndex]);
        overdialog.cancel();
    }

三、WheelView核心类–自定义滚轮控件

3.1 阴影效果的实现
采取的是8位颜色值,同时开始颜色和结束颜色除了透明度不一致外,其rgb的值是一致的,核心代码如下:

//初始化资源
 private void initResourcesIfNecessary() {
        if (centerDrawable == null) {
            centerDrawable = getContext().getResources().getDrawable(wheelForeground);
        }
        //计算阴影开始颜色到阴影结束颜色的范围值
        range = (int) ((Long.parseLong(Integer.toHexString(SHADOWS_START_COLORS - SHADOWS_END_COLORS), 16)) >> 28);

        int colorItems = (visibleItems - 1) / 2;
        //阴影颜色数组,加2是因为要开始颜色和结束颜色
        SHADOWS_COLORS = new int[colorItems + 2];
        SHADOWS_COLORS[0] = SHADOWS_START_COLORS;
        SHADOWS_COLORS[SHADOWS_COLORS.length - 1] = SHADOWS_END_COLORS;
        //计算每个条目之间颜色的差值
        int itemChange = range / SHADOWS_COLORS.length;
        //计算开始颜色的透明度
        int maxRange = (int) ((Long.parseLong(Integer.toHexString(SHADOWS_START_COLORS & 0xF0000000), 16)) >> 28);
        //获取颜色值的后7位
        int finalRange = SHADOWS_END_COLORS & 0x0fffffff;
        for (int i = 0; i < SHADOWS_COLORS.length; i++) {
            if (i == 0 || i == SHADOWS_COLORS.length - 1) {
                continue;
            }
            SHADOWS_COLORS[i] = (int) Long.parseLong(Integer.toHexString(maxRange - i * itemChange) + Integer.toHexString(finalRange), 16);

        }
        //创建上半部分的渐变Drawable对象
        if (topShadow == null) {
            topShadow = new GradientDrawable(Orientation.TOP_BOTTOM, SHADOWS_COLORS);
        }
        //创建下半部分的渐变Drawable对象
        if (bottomShadow == null) {
            bottomShadow = new GradientDrawable(Orientation.BOTTOM_TOP, SHADOWS_COLORS);
        }

        setBackgroundResource(wheelBackground);
    }
//绘画阴影
private void drawShadows(Canvas canvas) {
        //根据滚轮的可视条目数来计算要被阴影覆盖的条目
        int shadowItem = (visibleItems - 1) / 2;
        //计算阴影的高度
        int height = (int) (shadowItem * getItemHeight());
        //画控件中心条目上半部分的阴影效果
        topShadow.setBounds(0, 0, getWidth(), height);
        topShadow.draw(canvas);
        //画控件中心条目下半部分的阴影效果
        bottomShadow.setBounds(0, getHeight() - height, getWidth(), getHeight());
        bottomShadow.draw(canvas);
    }

3.2 条目单击效果的处理

  //针对条目单击事件的处理了,判断当前点击位置是否有效
if (isValidItemIndex(currentItem + items)) {
   int item = currentItem + items;
   int dataCount = viewAdapter.getItemsCount();
   if (item < 0) {
        item = item + dataCount;
   } else if (item >= dataCount) {
        item = item - dataCount;
   }
   //通知条目点击事件的监听器
   notifyClickListenersAboutClick(item);
}

四、ArrayWheelAdapter和NumericWheelAdapter

这两个适配器是和WheelView结合使用的,用于给WheelView填充数据。
4.1 ArrayWheelAdapter数组适配器的用法

//创建适配
ArrayWheelAdapter<String> arrayAdapter = new ArrayWheelAdapter<>(context, this.mDatas);
//设置适配器
wv.setViewAdapter(arrayAdapter);

4.2 NumericWheelAdapter数字适配器的用法

 //设置适配器
 NumericWheelAdapter numericWheelAdapter = new NumericWheelAdapter(context, 1, getDay(arg1, arg2), "%02d");
//创建标签
numericWheelAdapter.setLabel(" 日");

本篇博客中的自定义控件WheelView的原型是在极光源码中抽取出来的,本人修复其中目前为止复现的Bug,有什么不足请见谅。

Demo源码的下载地址:
https://github.com/Duckdan/DefineDialogDemo

你可能感兴趣的:(Android技巧--对话框)