Android-PickerView

repository·master·Indexed 12 days ago

https://github.com/bigkoo/android-pickerview

A library providing specialized selection UI components for Android applications, such as 3D wheel pickers. It includes TimePickerView for date and time selection via TimePickerBuilder, and OptionsPickerView for hierarchical multi-level selection via OptionsPickerBuilder. The library also provides a standalone WheelView component for basic wheel scrolling logic. Version 4.1.9 is available, though the project has stopped receiving updates.

Tokens
7.2K
Snippets
13
Records
14
Agent score
46%

What's inside Android-PickerView

  1. Customize Picker Layout

    master

    You can provide a custom XML layout for the picker using .setLayoutRes(int layoutRes, CustomListener listener).

    CRITICAL: When using a custom layout, you must NOT modify the IDs of the child widgets (e.g., for OptionsPicker or TimePicker). Doing so will cause a NullPointerException.

    In the customLayout callback, you can manually handle clicks for the submit and cancel buttons using pv.returnData(view) and pv.dismiss() respectively.

      private void initCustomTimePicker() {
            // be careful: In the custom layout, the layout of the ID for optionspicker
            // or TimePicker and its child widget must not be modified,
            // otherwise will be reported NullPointerException
    
            Calendar selectedDate = Calendar.getInstance();
            Calendar startDate = Calendar.getInstance();
            startDate.set(2013,1,23);
            Calendar endDate = Calendar.getInstance();
            endDate.set(2019,2,28);
    
            pvCustomTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
                @Override
                public void onTimeSelect(Date date, View v) {
                    btn_CustomTime.setText(getTime(date));
                }
            })       .setType(new boolean[]{true, true, true, false, false, false})// year - month - day
                    .setDate(selectedDate)
                    .setRangDate(startDate,endDate)
                    .setLayoutRes(R.layout.pickerview_custom_time, new CustomListener() {
    
                        @Override
                        public void customLayout(View v) {
                            final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish);
                            ImageView ivCancel = (ImageView) v.findViewById(R.id.iv_cancel);
                            tvSubmit.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    pvCustomTime.returnData(tvSubmit);
                                }
                            });
                            ivCancel.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    pvCustomTime.dismiss();
                                }
                            });
                        }
                    })
                    .setDividerColor(Color.BLACK)
                    .build();
        }
  2. Implement custom layouts for PickerView

    master

    You can provide a custom XML layout for the picker.

    Important: The layout must contain views with IDs matching optionspicker or timepicker and their sub-controls, otherwise a NullPointerException will occur. Refer to the project's demo for valid layout structures.

    Usage:

            pvCustomOptions = new OptionsPickerBuilder(this, new OptionsPickerView.OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int options2, int options3, View v) {
                    String tx = cardItem.get(options1).getPickerViewText();
                    btn_CustomOptions.setText(tx);
                }
            })
                    .setLayoutRes(R.layout.pickerview_custom_options, new CustomListener() {
                        @Override
                        public void customLayout(View v) {
                            // Initialize views and handle events
                            final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish);
                            tvSubmit.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    pvCustomOptions.returnData(tvSubmit);
                                }
                            });
                            // ... other view logic
                        }
                    })
                    .build();
            pvCustomOptions.setPicker(cardItem);
            // 注意:自定义布局中,id为 optionspicker 或者 timepicker 的布局以及其子控件必须要有,否则会报空指针
            // 具体可参考demo 里面的两个自定义布局
            pvCustomOptions = new OptionsPickerBuilder(this, new OptionsPickerView.OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int options2, int options3, View v) {
                    String tx = cardItem.get(options1).getPickerViewText();
                    btn_CustomOptions.setText(tx);
                }
            })
                    .setLayoutRes(R.layout.pickerview_custom_options, new CustomListener() {
                        @Override
                        public void customLayout(View v) {
                            //自定义布局中的控件初始化及事件处理
                            final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish);
                            final TextView tvAdd = (TextView) v.findViewById(R.id.tv_add);
                            ImageView ivCancel = (ImageView) 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();
                                }
                            });
    
                            tvAdd.setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    getData();
                                    pvCustomOptions.setPicker(cardItem);
                                }
                            });
                        }
                    })
                    .build();
            pvCustomOptions.setPicker(cardItem);
  3. Install Android-PickerView

    master

    Add the dependency to your Android project using either Gradle or Maven.

    Gradle

    compile 'com.contrarywind:Android-PickerView:4.1.9'

    Maven

    <dependency>
    <groupId>com.contrarywind</groupId>
    <artifactId>Android-PickerView</artifactId>
    <version>4.1.8</version>
    <type>pom</type>
    </dependency>
  4. Use WheelView as a standalone component

    master

    If you only need the underlying wheel scrolling logic without the full PickerView features, you can include the wheelview library separately.

    Gradle dependency:

    compile 'com.contrarywind:wheelview:4.1.0'

    XML Layout:

     <com.contrarywind.view.WheelView
                android:id:@+id/wheelview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

    Java Usage:

    WheelView wheelView = findViewById(R.id.wheelview);
    wheelView.setCyclic(false);
    
    final List<String> mOptionsItems = new ArrayList<>();
    mOptionsItems.add("item0");
    mOptionsItems.add("item1");
      
    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();
        }
    });
     <com.contrarywind.view.WheelView
                android:id="@+id/wheelview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
  5. Install Android-PickerView via Gradle or Maven

    master

    To use Android-PickerView in your Android project, add the dependency to your build.gradle file. Note that the project has stopped updating, but the existing JCenter version remains usable. It is recommended to download the source code and include it as a module for customization.

    Gradle dependency:

    compile 'com.contrarywind:Android-PickerView:4.1.9'

    Maven dependency:

    <dependency>
    <groupId>com.contrarywind</groupId>
    <artifactId>Android-PickerView</artifactId>
    <version>4.1.9</version>
    <type>pom</type>
    </dependency>
  6. Important notice regarding project maintenance

    master

    ⚠️ Attention: This project has stopped receiving updates.

    While existing versions available via JCenter can still be used, it is highly recommended that you download the source code and import the module directly into your project to perform your own modifications and ensure long-term compatibility.

  7. Important: Handling Calendar months in TimePickerView

    master

    When setting the start or end dates for a TimePickerView, you must account for the fact that the Calendar component uses 0-based indexing for months (0-11 represents January-December).

    Incorrect usage:

    startDate.set(2013, 1, 1); // This sets it to February
    date.set(2020, 12, 1);     // This is out of bounds

    Correct usage:

    startDate.set(2013, 0, 1); // This sets it to January
    date.set(2020, 11, 1);     // This sets it to December
     //正确使用案例:
     startDate.set(2013,0,1);
     endDate.set(2020,11,1);
  8. Use TimePickerView for date and time selection

    master

    Use TimePickerBuilder to create a time picker. You can specify formats (Year, Month, Day, Hour, Minute, Second) using .setType().

    Basic Usage:

    TimePickerView pvTime = new TimePickerBuilder(MainActivity.this, new OnTimeSelectListener() {
        @Override
        public void onTimeSelect(Date date, View v) {
            Toast.makeText(MainActivity.this, getTime(date), Toast.LENGTH_SHORT).show();
        }
    }).build();

    Customization Example:

     pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
                @Override
                public void onTimeSelect(Date date,View v) {
                    tvTime.setText(getTime(date));
                }
            })
                    .setType(new boolean[]{true, true, true, true, true, true})
                    .setCancelText("Cancel")
                    .setSubmitText("Sure")
                    .setContentSize(18)
                    .setTitleSize(20)
                    .setTitleText("Title")
                    .setOutSideCancelable(false)
                    .isCyclic(true)
                    .setTitleColor(Color.BLACK)
                    .setSubmitColor(Color.BLUE)
                    .setCancelColor(Color.BLUE)
                    .setTitleBgColor(0xFF666666)
                    .setBgColor(0xFF333333)
                    .setDate(selectedDate)
                    .setRangDate(startDate,endDate)
                    .setLabel("年","月","日","时","分","秒")
                    .isCenterLabel(false)
                    .isDialog(true)
                    .build();
    //时间选择器
    TimePickerView pvTime = new TimePickerBuilder(MainActivity.this, new OnTimeSelectListener() {
                               @Override
                               public void onTimeSelect(Date date, View v) {
                                   Toast.makeText(MainActivity.this, getTime(date), Toast.LENGTH_SHORT).show();
                               }
                           }).build();
  9. Use OptionsPickerView for multi-level selection

    master

    Use OptionsPickerBuilder to create a picker for hierarchical data (e.g., Province > City > District). It supports up to three levels of selection and can be configured for linkage (cascading) or independent selection.

    Basic Usage:

     OptionsPickerView pvOptions = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
                    String tx = options1Items.get(options1).getPickerViewText()
                            + options2Items.get(options1).get(option2)
                            + options3Items.get(options1).get(option2).get(options3).getPickerViewText();
                    tvOptions.setText(tx);
                }
            }).build();
     pvOptions.setPicker(options1Items, options2Items, options3Items);
     pvOptions.show(); 

    Customization Example:

    pvOptions = new  OptionsPickerBuilder(this, new OptionsPickerView.OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
                    // ... implementation
                }
            }) .setOptionsSelectChangeListener(new OnOptionsSelectChangeListener() {
                                  @Override
                                  public void onOptionsSelectChanged(int options1, int options2, int options3) {
                                      // ... implementation
                                  }
                              })
                    .setSubmitText("确定")
                    .setCancelText("取消")
                    .setTitleText("城市选择")
                    .setSubCalSize(18)
                    .setTitleSize(20)
                    .setTitleColor(Color.BLACK)
                    .setSubmitColor(Color.BLUE)
                    .setCancelColor(Color.BLUE)
                    .setTitleBgColor(0xFF333333)
                    .setBgColor(0xFF000000)
                    .setContentTextSize(18)
                    .setLinkage(false)
                    .setLabels("省", "市", "区")
                    .isCenterLabel(false)
                    .setCyclic(false, false, false)
                    .setSelectOptions(1, 1, 1)
                    .setOutSideCancelable(false)
                    .isDialog(true)
                    .isRestoreItem(true)
                    .build();
    
    pvOptions.setPicker(options1Items, options2Items, options3Items);
    //条件选择器
     OptionsPickerView pvOptions = new OptionsPickerBuilder(MainActivity.this, new OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
                    //返回的分别是三个级别的选中位置
                    String tx = options1Items.get(options1).getPickerViewText()
                            + options2Items.get(options1).get(option2)
                            + options3Items.get(options1).get(option2).get(options3).getPickerViewText();
                    tvOptions.setText(tx);
                }
            }).build();
     pvOptions.setPicker(options1Items, options2Items, options3Items);
     pvOptions.show(); 
  10. Use Non-Linkage Data in OptionsPicker

    master

    If you want to use multiple pickers that are not linked to each other (e.g., selecting food, clothes, and computer independently), use the .setNPicker(List... lists) method instead of .setPicker().

    // Non-linkage options
     pvNoLinkOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
    
                @Override
                public void onOptionsSelect(int options1, int options2, int options3, View v) {
    
                    String str = "food:" + food.get(options1)
                            + "\nclothes:" + clothes.get(options2)
                            + "\ncomputer:" + computer.get(options3);
    
                    Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
                }
            }).build();
     pvNoLinkOptions.setNPicker(food, clothes, computer);
     pvNoLinkOptions.show();
  11. Use OptionsPickerView

    master

    Use OptionsPickerBuilder to create a picker for custom options. It supports up to three levels of linkage (e.g., Province > City > District).

    To set the data, use .setPicker() with the appropriate number of data lists (up to 3).

    //OptionsPicker
     pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
                @Override
                public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
                    ////Callback
                    String tx = options1Items.get(options1).getPickerViewText()
                            + options2Items.get(options1).get(option2)
                            + options3Items.get(options1).get(option2).get(options3).getPickerViewText();
                    tvOptions.setText(tx);
                }
            }).build();
    
     //pvOptions.setPicker(options1Items);
     pvOptions.setPicker(options1Items, options2Items);
     //pvOptions.setPicker(options1Items, options2Items, options3Items);
     pvOptions.show();
  12. Customize TimePickerView

    master

    You can customize the appearance and behavior of the TimePickerBuilder using various setter methods.

    Key customization methods:

    • .setType(boolean[]): Set which units (year, month, day, etc.) are visible.
    • .setRangDate(startDate, endDate): Set the selectable date range.
    • .setLabel(String...): Customize the unit labels.
    • .isCyclic(boolean): Enable/disable cyclic scrolling.
    • .setCancelText(String) / .setSubmitText(String): Customize button text.
    • .setBgColor(int) / .setTitleBgColor(int): Customize background colors.
     Calendar selectedDate = Calendar.getInstance();
     Calendar startDate = Calendar.getInstance();
     startDate.set(2013,0,1);
     Calendar endDate = Calendar.getInstance();
     endDate.set(2020,11,1);
    
     pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
                @Override
                public void onTimeSelect(Date date,View v) {//callback
                    tvTime.setText(getTime(date));
                }
            })
                    .setType(new boolean[]{false, false, false, true, true, false})// type of date 
                    .setCancelText("Cancel")
                    .setSubmitText("Sure")
                    .setContentSize(18)
                    .setTitleSize(20)
                    .setTitleText("Title")
                    .setOutSideCancelable(false)// default is true
                    .isCyclic(true)// default is false
                    .setTitleColor(Color.BLACK)
                    .setSubmitColor(Color.BLUE)
                    .setCancelColor(Color.BLUE)
                    .setTitleBgColor(0xFF666666)//night mode
                    .setBgColor(0xFF333333)//night mode
                    .setRangDate(startDate,endDate)
                    .setLabel("year","month","day","hours","mins","seconds")
                    .build();