Android-PickerView 完全指南:时间选择器与省市区联动解决方案

Android-PickerView 完全指南:时间选择器与省市区联动解决方案

【免费下载链接】Android-PickerView This is a picker view for android , support linkage effect, timepicker and optionspicker.(时间选择器、省市区三级联动) 【免费下载链接】Android-PickerView 项目地址: https://gitcode.com/gh_mirrors/an/Android-PickerView

1. 项目概述

Android-PickerView 是一个功能强大的 Android 选择器组件库,支持时间选择器(TimePicker)和选项选择器(OptionsPicker),特别适合实现省市区三级联动等复杂选择场景。该库提供了丰富的自定义选项和灵活的配置方式,能够满足各种界面需求。

1.1 核心功能

  • 时间选择器(TimePickerView):支持年月日时分秒等多种时间格式选择
  • 选项选择器(OptionsPickerView):支持一、二、三级联动选择
  • 高度自定义:可自定义布局、颜色、文字大小、滚轮样式等
  • 丰富的交互:支持循环滚动、联动效果、实时回调等功能

1.2 应用场景

mermaid

2. 快速开始

2.1 环境准备

Android-PickerView 要求 Android API 级别 9+,兼容几乎所有现代 Android 设备。

2.2 安装方式

2.2.1 Gradle 依赖
dependencies {
    implementation 'com.contrarywind:Android-PickerView:4.1.9'
}
2.2.2 源码集成

如果需要自定义修改或贡献代码,可以直接克隆仓库:

git clone https://gitcode.com/gh_mirrors/an/Android-PickerView.git

然后将 pickerviewwheelview 模块导入到你的 Android 项目中。

3. 核心组件详解

3.1 WheelView 基础控件

WheelView 是整个库的基础组件,提供了滚轮选择的核心功能。

// XML布局中添加
<com.contrarywind.view.WheelView
    android:id="@+id/wheelview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

// Java代码中配置
WheelView wheelView = findViewById(R.id.wheelview);
wheelView.setCyclic(false); // 是否循环滚动
wheelView.setAdapter(new ArrayWheelAdapter(mOptionsItems)); // 设置适配器
wheelView.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(int index) {
        // 选中项变化回调
        Toast.makeText(MainActivity.this, mOptionsItems.get(index), Toast.LENGTH_SHORT).show();
    }
});

WheelView 主要方法:

方法描述
setCyclic(boolean cyclic)设置是否循环滚动
setCurrentItem(int currentItem)设置当前选中项
setAdapter(WheelAdapter adapter)设置数据适配器
setOnItemSelectedListener(OnItemSelectedListener listener)设置选中项变化监听器
setItemsVisibleCount(int visibleCount)设置可见项数量
setAlphaGradient(boolean alphaGradient)设置是否启用透明度渐变效果

3.2 时间选择器(TimePickerView)

时间选择器用于选择日期和时间,支持多种时间格式和自定义选项。

3.2.1 基本用法
// 初始化时间选择器
Calendar selectedDate = Calendar.getInstance();
Calendar startDate = Calendar.getInstance();
startDate.set(2000, 0, 1);
Calendar endDate = Calendar.getInstance();
endDate.set(2030, 11, 31);

TimePickerView pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
    @Override
    public void onTimeSelect(Date date, View v) {
        // 选中时间回调
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String time = sdf.format(date);
        Toast.makeText(MainActivity.this, time, Toast.LENGTH_SHORT).show();
    }
})
.setType(new boolean[]{true, true, true, true, true, false}) // 年月日时分秒显示与否
.setRangDate(startDate, endDate) // 设置时间范围
.setTitleText("选择时间") // 设置标题
.build();

// 显示时间选择器
pvTime.show();
3.2.2 时间选择器配置项
TimePickerView pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
    @Override
    public void onTimeSelect(Date date, View v) {
        // 时间选择回调
    }
})
.setType(new boolean[]{true, true, true, false, false, false}) // 只显示年月日
.setCancelText("取消") // 取消按钮文字
.setSubmitText("确定") // 确认按钮文字
.setContentSize(18) // 滚轮文字大小
.setTitleSize(20) // 标题文字大小
.setTitleColor(Color.BLACK) // 标题文字颜色
.setSubmitColor(Color.BLUE) // 确认按钮文字颜色
.setCancelColor(Color.BLUE) // 取消按钮文字颜色
.setTitleBgColor(0xFFEEEEEE) // 标题背景颜色
.setBgColor(0xFFFFFFFF) // 滚轮背景颜色
.setDate(selectedDate) // 设置默认选中时间
.setRangDate(startDate, endDate) // 设置时间范围
.setLabel("年", "月", "日", "时", "分", "秒") // 设置单位标签
.isCenterLabel(false) // 是否只显示中间选中项的标签
.isCyclic(true) // 是否循环滚动
.setOutSideCancelable(true) // 点击外部是否取消
.isDialog(true) // 是否以对话框形式显示
.build();

3.3 选项选择器(OptionsPickerView)

选项选择器用于实现单项、多项或联动选择功能,最典型的应用是省市区三级联动。

3.3.1 基础用法
// 准备数据
List<String> options1Items = new ArrayList<>();
List<List<String>> options2Items = new ArrayList<>();
List<List<List<String>>> options3Items = new ArrayList<>();

// 初始化数据...

// 创建选项选择器
OptionsPickerView pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
    @Override
    public void onOptionsSelect(int options1, int option2, int options3, View v) {
        // 返回的分别是三个级别的选中位置
        String tx = options1Items.get(options1) + 
                   options2Items.get(options1).get(option2) + 
                   options3Items.get(options1).get(option2).get(options3);
        Toast.makeText(MainActivity.this, tx, Toast.LENGTH_SHORT).show();
    }
})
.setTitleText("城市选择")
.setCyclic(false, false, false)
.setSelectOptions(0, 0, 0) // 设置默认选中项
.build();

// 设置数据源
pvOptions.setPicker(options1Items, options2Items, options3Items);

// 显示选择器
pvOptions.show();
3.3.2 三级联动数据结构

mermaid

三级联动需要的数据结构是:List<String>(一级)、List<List<String>>(二级)和 List<List<List<String>>>(三级)。

3.3.3 从JSON文件加载数据
// 使用工具类加载JSON数据
String jsonData = new GetJsonDataUtil().getJson(this, "province.json");
List<JsonBean> jsonBean = parseData(jsonData); // 解析JSON数据

// 填充数据
for (JsonBean jsonBean : jsonBeanList) {
    List<String> cityList = new ArrayList<>();
    List<List<String>> province_AreaList = new ArrayList<>();
    
    options1Items.add(jsonBean.getName());
    
    List<JsonBean.CityBean> cityBeanList = jsonBean.getCityList();
    for (JsonBean.CityBean cityBean : cityBeanList) {
        String cityName = cityBean.getName();
        cityList.add(cityName);
        
        List<String> areaList = cityBean.getArea();
        province_AreaList.add(areaList);
    }
    
    options2Items.add(cityList);
    options3Items.add(province_AreaList);
}

3. 高级自定义

3.1 自定义布局

Android-PickerView 支持完全自定义布局,以满足特殊的界面需求:

pvCustomOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
    @Override
    public void onOptionsSelect(int options1, int option2, int options3, View v) {
        // 选择回调
    }
})
.setLayoutRes(R.layout.pickerview_custom_options, new CustomListener() {
    @Override
    public void customLayout(View v) {
        // 自定义布局控件初始化
        TextView tvSubmit = v.findViewById(R.id.tv_finish);
        TextView tvAdd = v.findViewById(R.id.tv_add);
        ImageView ivCancel = v.findViewById(R.id.iv_cancel);
        
        // 设置事件监听
        tvSubmit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pvCustomOptions.returnData(tvSubmit);
            }
        });
        
        ivCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pvCustomOptions.dismiss();
            }
        });
    }
})
.build();

3.2 自定义滚轮样式

// 设置滚轮样式
.setDividerColor(Color.LTGRAY) // 分割线颜色
.setDividerType(WheelView.DividerType.CIRCLE) // 分割线类型
.setTextColorCenter(Color.BLACK) // 选中项文字颜色
.setTextColorOut(Color.GRAY) // 未选中项文字颜色
.setLineSpacingMultiplier(1.5f) // 行间距倍数
.setItemVisibleCount(5) // 可见项数量
.setAlphaGradient(true) // 启用透明度渐变

3.3 自定义动画效果

// 设置弹出动画
.setDecorView(null) // 设置自定义DecorView
.setOutSideColor(0x00000000) // 外部背景颜色

4. 实战案例

4.1 省市区三级联动

4.1.1 数据准备

首先,我们需要准备省市区数据,通常是JSON格式:

[
  {
    "name": "北京市",
    "city": [
      {
        "name": "北京市",
        "area": ["东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区"]
      }
    ]
  },
  // 更多省份...
]
4.1.2 实现代码
// 加载省市区数据
private void initJsonData() {
    String JsonData = new GetJsonDataUtil().getJson(this, "province.json");
    List<JsonBean> jsonBean = parseData(JsonData);
    
    for (JsonBean province : jsonBean) {
        options1Items.add(province.getName());
        
        List<String> cityList = new ArrayList<>();
        List<List<String>> provinceAreaList = new ArrayList<>();
        
        for (JsonBean.CityBean city : province.getCityList()) {
            cityList.add(city.getName());
            provinceAreaList.add(city.getArea());
        }
        
        options2Items.add(cityList);
        options3Items.add(provinceAreaList);
    }
}

// 显示选择器
private void showPickerView() {
    OptionsPickerView pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
        @Override
        public void onOptionsSelect(int options1, int option2, int options3, View v) {
            String address = options1Items.get(options1) + " " +
                           options2Items.get(options1).get(option2) + " " +
                           options3Items.get(options1).get(option2).get(options3);
            tvAddress.setText(address);
        }
    })
    .setTitleText("选择地区")
    .setLabels("省", "市", "区")
    .setCyclic(false, false, false)
    .build();
    
    pvOptions.setPicker(options1Items, options2Items, options3Items);
    pvOptions.show();
}

4.2 出生日期选择器

private void showBirthdayPicker() {
    Calendar startDate = Calendar.getInstance();
    startDate.set(1900, 0, 1);
    Calendar endDate = Calendar.getInstance();
    
    TimePickerView pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
        @Override
        public void onTimeSelect(Date date, View v) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            tvBirthday.setText(sdf.format(date));
        }
    })
    .setType(new boolean[]{true, true, true, false, false, false}) // 只显示年月日
    .setLabel("年", "月", "日", "", "", "")
    .setRangDate(startDate, endDate)
    .setTitleText("选择出生日期")
    .build();
    
    pvTime.show();
}

4.3 自定义主题选择器

private void showThemePicker() {
    List<String> themeList = new ArrayList<>();
    themeList.add("默认主题");
    themeList.add("深色主题");
    themeList.add("蓝色主题");
    themeList.add("绿色主题");
    
    OptionsPickerView pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
        @Override
        public void onOptionsSelect(int options1, int option2, int options3, View v) {
            applyTheme(options1); // 应用选中的主题
        }
    })
    .setTitleText("选择主题")
    .setContentTextSize(18)
    .setCyclic(false)
    .setSelectOptions(currentTheme) // 设置当前选中的主题
    .build();
    
    pvOptions.setPicker(themeList);
    pvOptions.show();
}

5. 性能优化

5.1 数据处理优化

  • 懒加载:对于大量数据,考虑使用懒加载方式,只加载当前需要显示的数据
  • 分页加载:如果数据量过大,考虑分页加载数据
  • 数据复用:避免频繁创建和销毁数据对象

5.2 内存管理

  • 及时销毁:不需要时及时调用dismiss()方法销毁PickerView
  • 避免内存泄漏:使用弱引用(WeakReference)保存上下文
// 使用弱引用避免内存泄漏
private WeakReference<Context> mContextWeakReference;

// 初始化
mContextWeakReference = new WeakReference<>(context);

// 使用时检查
if (mContextWeakReference.get() != null) {
    // 执行操作
}

5.3 滑动优化

  • 减少绘制:避免在滚动过程中执行复杂的绘制操作
  • 平滑滚动:使用平滑滚动代替瞬时跳转
// 使用平滑滚动
wheelView.smoothScroll(WheelView.ACTION.FLING);

6. 常见问题与解决方案

6.1 时间选择器月份设置问题

问题:设置月份时出现错位,如设置2月实际显示3月。

原因:Calendar类的月份是从0开始的(0-11代表1-12月)。

解决方案

// 错误方式
startDate.set(2020, 1, 1); // 实际会设置为2020年2月

// 正确方式
startDate.set(2020, 0, 1); // 设置为2020年1月
endDate.set(2020, 11, 31); // 设置为2020年12月

6.2 数据为空导致崩溃

问题:当数据源为空时,PickerView可能会崩溃。

解决方案

// 使用前检查数据是否为空
if (options1Items != null && !options1Items.isEmpty()) {
    pvOptions.setPicker(options1Items, options2Items, options3Items);
    pvOptions.show();
} else {
    Toast.makeText(this, "暂无数据", Toast.LENGTH_SHORT).show();
}

6.3 自定义布局不显示

问题:自定义布局后PickerView不显示或显示异常。

解决方案

  • 确保自定义布局中包含id为optionspickertimepicker的布局
  • 检查自定义布局的根布局是否设置了正确的属性
  • 确保自定义布局中的控件id与代码中引用的一致

7. 版本迁移指南

7.1 从3.x迁移到4.x

4.x版本相比3.x版本有一些API变化,主要包括:

  • 方法重命名:setBackgroundId() 改为 setOutSideColor()
  • 新增功能:支持设置最大可见项数量、透明度渐变等
  • 回调接口调整:部分回调方法参数变化

迁移示例:

// 3.x版本
pvTime.setBackgroundId(0x00000000);

// 4.x版本
pvTime.setOutSideColor(0x00000000);

8. 总结与展望

Android-PickerView 是一个功能强大且高度可定制的选择器库,通过提供时间选择器和选项选择器,极大地简化了Android应用中复杂选择功能的实现。其丰富的自定义选项和灵活的配置方式,能够满足各种界面需求。

8.1 主要优势

  • 功能全面:覆盖了时间选择和选项选择的各种需求
  • 高度自定义:从布局到样式都可以深度定制
  • 性能优良:优化的滚轮实现,流畅的滚动体验
  • 易于集成:简单几步即可集成到项目中

8.2 未来展望

  • 支持更多自定义动画效果
  • 增加更多内置主题
  • 优化大数据场景下的性能
  • 支持更多交互方式

9. 附录

9.1 完整API参考

类名主要方法描述
TimePickerViewsetDate(Calendar date)设置默认日期
setRangDate(Calendar start, Calendar end)设置日期范围
setType(boolean[] type)设置显示的时间类型
setLunarCalendar(boolean lunar)设置是否显示农历
OptionsPickerViewsetPicker(List<T> items)设置数据源
setSelectOptions(int... options)设置默认选中项
setLabels(String... labels)设置单位标签
setLinkage(boolean linkage)设置是否联动
BasePickerViewshow()显示选择器
dismiss()关闭选择器
setOnDismissListener(OnDismissListener listener)设置关闭监听器
setOutSideCancelable(boolean cancelable)设置点击外部是否关闭

9.2 资源下载

9.3 贡献指南

如果你发现bug或有功能需求,可以通过以下方式贡献:

  1. Fork本仓库
  2. 创建分支 (git checkout -b feature/amazing-feature)
  3. 提交更改 (git commit -m 'Add some amazing feature')
  4. 推送到分支 (git push origin feature/amazing-feature)
  5. 创建Pull Request

【免费下载链接】Android-PickerView This is a picker view for android , support linkage effect, timepicker and optionspicker.(时间选择器、省市区三级联动) 【免费下载链接】Android-PickerView 项目地址: https://gitcode.com/gh_mirrors/an/Android-PickerView

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值