本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
一个非常好用的 Android PickerView 库
kenrry1992 · 796浏览量 · 发布于2019-05-27 +关注

作者jaaksi,源码pickerview,一个非常好用的 Android PickerView 库,内部提供 3 种常用类型的 Picker,支持扩展自定义 Picker:

  • TimePicker:时间选择器,支持聚合模式的时间选择器(合并 v1.x 的 MixedTimePicker)

  • OptionPicker:联动选择器

效果图

  

APK

Demo App下载连接

PickerView README

Picker

通过组装 PickerView 实现常用的 Picker 选择器。上面已经列举提供的 3 中常用的 Picker。

BasePicker

Picker 基类:封装了 TopBar,PickerView 容器,create and add PickerView 方法,Picker 弹窗等方法。 三种 Picker 都继承自 BasePicker,你也可以继承它扩展自己的 Picker。

API


apidescription

setPickerBackgroundColor设置 picker 背景

setPadding设置 PickerView 父容器 padding 单位:px

setTag给 Picker 设置 tag,用于区分不同的 picker 等。用法同 View setTag

getRootLayout获取 PickerView 的父容器,创建 DefaultTopBar 时必须指定

setOnPickerChooseListener设置 picker 取消,确定按钮监听。可用于拦截选中操作

setTopBar设置自定义 TopBar

setInterceptor设置拦截器

createPickerView创建 PickerView

getPickerViews获取 Picker 中所有的 pickerview 集合

addPicker将创建的 PickerView 添加到上面集合中,createPickerView 内部已调用该方法

findPickerViewByTag通过 tag 找到对应的 PickerView

isScrolling是否滚动未停止。滚动未停止的时候,不响应 Picker 的取消,确定按键

getPickerDialog获取 Picker 弹窗。可以在 new 之后设置 dialog 属性

show显示 picker 弹窗

对比 github 上最受欢迎的同类库 Android-PickerView ,本库将 TopBar 等通用相关逻辑封装在基类中,并提供代码中创建 PickerView 方法,不需要再依赖 xml。用户自定义 Picker 时,继承 BasePicker,只需要处理自己的逻辑即可,简单便捷。 而对 Android-PickerView 来说,实现自定义 Picker,依然需要处理 TopBar 等逻辑,造成大量重复代码。

TopBar

TopBar:TopBar 通过抽象接口 ITopBar 来管理,实现 Picker 与 TopBar 的解耦。提供默认实现 DefaultTopBar。可实现接口定制自己的 TopBar。

   public interface ITopBar {
     /**
      * @return topbar view
      */
     View getTopBarView();

     /**
      * @return 取消按钮 view
      */
     View getBtnCancel();

     /**
      * @return 确定按钮 view
      */
     View getBtnConfirm();

     /**
      * @return title view
      */
     TextView getTitleView();
   }

DefaultTopBar API


apidescription

setDividerColor设置 topbar bottom line color

setDividerHeight设置 bottom divider line height

getDivider获取 TopBar bottom line

getTitleView获取 TopBar title view

Interceptor

拦截器:用于在 pickerview 创建时拦截,设置 pickerview 的属性。

Picker 内部并不提供对 PickerView 的设置方法,而是通过 Interceptor 实现。这种设计用来实现 Picker 和 PickerView 的属性设置完美解耦。

   private void init(){
    mTimePicker.setInterceptor(new BasePicker.Interceptor() {
      @Override public void intercept(PickerView pickerView, LinearLayout.LayoutParams params) {
        pickerView.setVisibleItemCount(5);
        // 将年月设置为循环的
        int type = (int) pickerView.getTag();
        if (type == TimePicker.TYPE_YEAR || type == TimePicker.TYPE_MONTH) {
          pickerView.setIsCirculation(true);
        }
      }
    })
   }

这一点对比 Android-PickerView, 每个 Picker 都需要声明对 PickerView 的设置方法,与 PickerView 严重耦合。需要开发者 copy 大量重复代码,且无法区分每一个 PickerView 设置不同的属性。

TimePicker

常用的时间选择器,支持 年、月、日、时、分,支持聚合(1.x 的 MixTimePicker)

  • 时间类型 type 的设计:自由组合、随心所欲(当然应该是有意义的)

    TYPE_YEAR | TYPE_MONTH | TYPE_DAY | TYPE_HOUR | TYPE_MINUTE
    
    TYPE_MIXED_DATE | TYPE_MIXED_TIME

    对比 Android-PickerView TimePickerView

    /**
    * Android-PickerView 中的设置 type 方法:参数设置麻烦且不易理解
    * 长度必须为 6 的数组,表示年月日时分秒 的显示与否,不设置则默认全部显示
    */
    setType(boolean[] type)
    
    // 本项目设置 type 方法:简单易懂,组合方便
    setType(TYPE_DATE | TYPE_HOUR)
  • 完美支持时间区间设置以及选中联动

  • 支持支持自定义日期、时间格式(Format),如显示今年,明年

  • 支持混合模式,支持日期,时间混合

  • 支持设置时间间隔,如 30 分钟

API


apidescription

type时间类型,需要在 Builder 构造方法中指定,不能改变

OnTimeSelectListener选中时间回调,需要在 Builder 构造方法中指定,不能改变

setRangDate设置起止时间

setSelectedDate设置选中时间戳

setInterceptor设置拦截器

setFormatter设置 Formatter,内部提供默认的 Formatter

create通过 Builder 构建 TimePicker


以上是 TimePicker.Builder 的,下面是 TimePicker 的

setFormatter同上

setSelectedDate同上

getType获取 type

hasType判断是否包含某种 type

Formatter

TimePicker Formatter:用于根据 type 和 num 格式化时间文案

    public interface Formatter {
        /**
         * 根据 type 和 num 格式化时间
         *
         * @param picker picker
         * @param type 并不是模式,而是当前 item 所属的 type,如年,时
         * @param position position
         * @param value position item 对应的 value,如果是 TYPE_MIXED_DATE 表示日期时间戳,否则表示显示的数字
         */
        CharSequence format(TimePicker picker, int type, int position,
          long value);
      }

内部提供默认的 Formatter 实现 DefaultFormatter。用户可以设置自定义 Formatter 或继承 DefaultFormatter 进行扩展。

TimePicker 初始化,如果未设置时间区间,会使用默认区间。三种 Picker 都采用 Builder 模式初始化。且用户自定义的 Picker 也应该采用这种模式进行初始化。

Simple Example

    mTimePicker = new TimePicker.Builder(mActivity, type, this)
      // 设置时间区间
      .setRangDate(1526361240000L, 1893563460000L)
      // 设置选中时间
      //.setSelectedDate()
      // 设置 pickerview 样式
      .setInterceptor(new BasePicker.Interceptor() {
        @Override public void intercept(PickerView pickerView, LinearLayout.LayoutParams params) {
          pickerView.setVisibleItemCount(5);
          // 将年月设置为循环的
          int type = (int) pickerView.getTag();
          if (type == TimePicker.TYPE_YEAR || type == TimePicker.TYPE_MONTH) {
            pickerView.setIsCirculation(true);
          }
        }
      })
      // 设置 Formatter
      .setFormatter(new TimePicker.DefaultFormatter() {
        // 自定义 Formatter 显示去年,今年,明年
        @Override
        public CharSequence format(TimePicker picker, int type, int position, long num) {
          if (type == TimePicker.TYPE_YEAR) {
            long offset = num - mCurrYear;
            if (offset == -1) return "去年";
            if (offset == 0) return "今年";
            if (offset == 1) return "明年";
            return num + "年";
          } else if (type == TimePicker.TYPE_MONTH) {
            return String.format("%d 月", num);
          }

          return super.format(picker, type, position, num);
        }
      }).create();

    //mTimePicker.setSelectedDate(1549349843000L);
    mTimePicker.show();

MixedTimePicker

1.x 版本,2.x 后已经与 TimePicker 合并。

OptionPicker

  • 支持设置层级

  • 支持联动和不联动(2.x 版本)

  • 构造数据源及其简单,只需要实现 OptionDataSet 接口

  • 支持通过对应选中的 values 设置选中项。内部处理选中项逻辑,避免用户记录下标且麻烦的遍历处理

对比 Android-PickerView 的 OptionsPickerView

functionAndroid-PickerViews本控件
多级最多支持 3 级(写死的)构造时设置级别(无限制)
构造数据源需要构建每一级的集合,二三级为嵌套一级数据 entity 实现 OptionDataSet 接口即可
设置数据源提供三个方法,分别用于一、二、三级的只需要设置一级数据集
联动选中提供三个,只能设置选中的下标。

需要用户自己通过多层遍历定位每一级别选中的下标,然后再设置只需要传入选中的 values(可变长数组),不需要任何计算

Android-PickerView 中的 OptionsPickerView 代码。由于不知道层级,所以每个方法都提供 3 个用来对应(最多)3 级选择。

    // 提供 3 个选中的方法,分别对应 1,2,3 级联动的情况
    public void setSelectOptions(int option1)

    public void setSelectOptions(int option1, int option2)

    public void setSelectOptions(int option1, int option2, int option3)

    // 提供 3 个设置数据源的方法,分别对应 1,2,3 级联动的情况
    public void setPicker(List<T> optionsItems)

    public void setPicker(List<T> options1Items, List<List<T>> options2Items)

    public void setPicker(List<T> options1Items, List<List<T>> options2Items,
          List<List<List<T>>> options3Items) {
    }

本库中的 OptionPicker(2.x)

/**
   * 根据选中的 values 初始化选中的 position
   *
   * @param values 选中数据的 value{@link OptionDataSet#getValue()},如果 values[0]==null,则进行默认选中,其他为 null 认为没有该列
   */
  public void setSelectedWithValues(String... values) {
    mDelegate.setSelectedWithValues(values);
  }

如上面对比表格中所列举的,无论是层级,构造数据源和设置数据源,还是设置选中的选项,本库的 API 都十分简单,方便。

API


apidescription

mHierarchy层级,需要在 Builder 构造方法中指定,不能改变

OnOptionSelectListener选中回调,需要在 Builder 构造方法中指定,不能改变

setInterceptor设置拦截器

setFormatter设置 Formatter

create通过 Builder 构建 OptionPicker


以上是 OptionPicker.Builder 的,下面是 OptionPicker 的

setFormatter同上

setData初始化 pickerview 数据。

setSelectedWithValues根据选中的 values 初始化选中的 position

getOptions获取数据集

getSelectedPosition获取选中的下标,数组 size=mHierarchy,如果为 -1 表示该列没有数据

getSelectedOptions获取选中的选项,如果指定 index 为 null 则表示该列没有数据

需要注意的是:本库中的 OptionPicker 只用于联动的,不支持多级别且不联动。 基本没有这种需求,如果大家有这种需求,我会在后续迭代中支持。

Others

奇葩设计:部分 default 属性声明为 static 而非 final

全局设置 default 属性

奇葩也好,亮点也罢。作为一个 UI 控件,不同的 app,不同的 UI,不同的产品自然会有不同的样式。 考虑到在一个 app 中我们会用到很多 Picker,而我们又需要定制自己的 UI 的样式,如果通过动态方法设置样式就太麻烦了。 故做此设计。你可以通过配置这些 static 变量来快速定制一个满足自己 app 样式需求的 Picker。 当然你也可以通过封装方法来处理 PickerView,Picker,装饰器等样式,但这样一样十分麻烦。我相信你自己都会烦。

静态默认值

所有的这些静态属性值都以 sDefault 开头

  • BasePickerView

fielddescriptiondefaultValue
sDefaultVisibleItemCount默认可见的 item 个数5
sDefaultItemSize默认 itemSize50(dp)
sDefaultIsCirculation默认是否循环false
  • PickerView

fielddescriptiondefaultValue
sOutTextSizedefault out text size18(dp)
sCenterTextSizedefault center text size22(dp)
sCenterColordefault center text colorColor.BLUE
sOutColordefault out text colorColor.GRAY
  • BasePicker

fielddescriptiondefaultValue
sDefaultPaddingRectpickerView 父容器的 default paddingnull(无 padding)
sDefaultPickerBackgroundColordefault picker background colorColor.WHITE
sDefaultTopBarCreator用于构建自定义 defaultTopBar 的接口null
  • DefaultCenterDecoration

fielddescriptiondefaultValue
sDefaultLineColordefault line colorColor.BLUE
sDefaultLineWidthdefault line width1(dp)
sDefaultDrawabledefault item background drawablenull
sDefaultMarginRectdefault line marginnull(无 margin)

建议初始化这些属性值放到 Application 中完成,避免 app 发生 crash 而导致失效

Simple Example

public class MyApplication extends Application {

  @Override public void onCreate() {
    super.onCreate();
    // 建议在 application 中初始化 picker 默认属性实现全局设置
    initDefaultPicker();
  }

  private void initDefaultPicker() {
    // 利用修改静态默认属性值,快速定制一套满足自己 app 样式需求的 Picker.
    // BasePickerView
    PickerView.sDefaultVisibleItemCount = 3;
    PickerView.sDefaultItemSize = 50;
    PickerView.sDefaultIsCirculation = true;

    // PickerView
    PickerView.sOutTextSize = 18;
    PickerView.sCenterTextSize = 18;
    PickerView.sCenterColor = Color.RED;
    PickerView.sOutColor = Color.GRAY;

    // BasePicker
    int padding = Util.dip2px(this, 20);
    BasePicker.sDefaultPaddingRect = new Rect(padding, padding, padding, padding);
    BasePicker.sDefaultPickerBackgroundColor = Color.WHITE;
    // 自定义 TopBar
    BasePicker.sDefaultTopBarCreator = new BasePicker.IDefaultTopBarCreator() {
      @Override public ITopBar createDefaultTopBar(LinearLayout parent) {
        return new CustomTopBar(parent);
      }
    };

    // DefaultCenterDecoration
    DefaultCenterDecoration.sDefaultLineWidth = 1;
    DefaultCenterDecoration.sDefaultLineColor = Color.RED;
    //DefaultCenterDecoration.sDefaultDrawable = new ColorDrawable(Color.WHITE);
    int leftMargin = Util.dip2px(this, 10);
    int topMargin = Util.dip2px(this, 2);
    DefaultCenterDecoration.sDefaultMarginRect =
      new Rect(leftMargin, -topMargin, leftMargin, -topMargin);
  }
}

Change Log

v2.0.0(2019-03-25)

  • release v2.0.0

  • 合并 MixedTimePicker 和 TimePicker,更强大 _ OptionPicker 支持数据不联动

  • 添加蒙版遮罩

  • 修复 fling 时可能会导致 onSelect 不回调等部分小 bug

  • 优化部分小细节

v1.0.0(2018-03-03)

  • release v1.0.0

v1.0.1(2018-04-13)

  • 修复 MixedTimePicker 选中时日期未更改

  • 修复部分手机 Picker 弹窗无法居底部

Gradle

    compile 'org.jaaksi:pickerview:2.0.0'


    源码使用过程中,如无法搭建或有增加其他功能需求,可联系QQ:236-0248-666 ,付费搭建安装修改服务!
    温馨提示:网站源码只作为学习或研究使用,如需商业使用请购买正版!

    相关推荐

    android日期选择器IngramTimeDialog源码

    相关信息 安卓巴士 · 653浏览 · 2021-02-19 14:33:14
    自定义布局和显示时间的Toast

    相关信息 kenrry1992 · 707浏览 · 2019-12-05 11:46:20
    一款仿小米UI的时钟 安卓源码

    相关信息 冷月葬花魂 · 705浏览 · 2019-12-04 12:00:33
    CalendarPicker日历选择器

    相关信息 匿名 · 3652浏览 · 2018-10-12 18:03:56
    Caldroid适用于Android的更好的日历

    相关信息 roomorama · 3580浏览 · 2018-08-20 17:45:06
    仿小米日历功能案例

    相关信息 匿名 · 3602浏览 · 2018-03-19 21:56:53
    calendar 日历的使用

    相关信息 匿名 · 3409浏览 · 2018-03-14 17:47:01
    自定义日历控件

    相关信息 匿名 · 3723浏览 · 2017-05-09 22:57:03
    加载中

    0评论

    评论
    • 源码信息
    • 所需 0 点数
    • 源码作者:匿名作者
    • 源码大小:2.450 MB
    • 源码类型:android源码
    • 显示语言: 简体中文
    • 运行环境:未知
    分类专栏
    小鸟云服务器
    扫码进入手机网页