第三方开源库之 Android-PickerView

目前最新版本是 4.1.9。
GitHub:https://github.com/Bigkoo/Android-PickerView

简介

Android-PickerView 是一款仿 iOS 的 PickerView 控件,带有 3D 圆弧效果,并封装了时间选择和选项选择这两种选择器。

配置

  1. 在 app/build.gradle 中添加依赖
1
implementation 'com.contrarywind:Android-PickerView:4.1.9'
  1. 自定义各种属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Calendar selectedDate = Calendar.getInstance();
 Calendar startDate = Calendar.getInstance();
 startDate.set(2013,1,1);
 Calendar endDate = Calendar.getInstance();
 endDate.set(2020,1,1);

 pvTime = new TimePickerBuilder(this, new TimePickerView.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)//标题背景颜色 Night mode
                .setBgColor(0xFF333333)//滚轮背景颜色 Night mode
                .setRange(calendar.get(Calendar.YEAR) - 20, calendar.get(Calendar.YEAR) + 20)//默认是1900-2100年
                .setDate(selectedDate)// 如果不设置的话,默认是系统时间*/
                .setRangDate(startDate,endDate)//起始终止年月日设定
                .setLabel("年","月","日","时","分","秒")
                .isDialog(true)//是否显示为对话框样式
                .build();

使用

效果图

  1. activity 布局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.PickViewActivity">

    <include
        android:id="@+id/include5"
        layout="@layout/layout_toolbar" />


    <Button
        android:id="@+id/button6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="224dp"
        android:text="时间选择器"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        app:layout_constraintBottom_toTopOf="@+id/button6"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/include5"
        app:layout_constraintVertical_bias="0.711" />


</androidx.constraintlayout.widget.ConstraintLayout>

  1. dialog 布局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#EEEEEE">

        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:background="#aaa" />

        <TextView
            android:id="@+id/iv_cancel"
            android:layout_width="61dp"
            android:layout_height="30dp"
            android:layout_centerVertical="true"
            android:gravity="center"
            android:layout_marginLeft="19dp"
            android:text="取消"
            android:textSize="16sp"
            android:background="@drawable/shape_white_black_7bg"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="选择时间"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="@color/black"
            android:layout_centerInParent="true"/>

        <TextView
            android:id="@+id/tv_finish"
            android:layout_width="61dp"
            android:layout_height="30dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="19dp"
            android:gravity="center"
            android:text="确定"
            android:background="@drawable/shape_yellow3_bg"
            android:textColor="@color/black"
            android:textSize="16sp" />

        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:background="#aaa" />
    </RelativeLayout>


    <!--此部分需要完整复制过去,删减或者更改ID会导致初始化找不到内容而报空-->
    <LinearLayout
        android:id="@+id/timepicker"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:orientation="horizontal">

        <com.contrarywind.view.WheelView
            android:id="@+id/year"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <com.contrarywind.view.WheelView

            android:id="@+id/month"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.1" />

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

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

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

        <com.contrarywind.view.WheelView
            android:id="@+id/second"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.1" />
    </LinearLayout>


</LinearLayout>
  1. shape 文件
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="@color/yellow" />
    <corners android:radius="3dp" />
</shape>
  1. Activity 类中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class PickViewActivity extends BaseActivity {

    @BindView(R.id.textView)
    TextView tvTime;

    private TimePickerView pvTime;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_pick_view;
    }

    @Override
    protected void setToolbar() {

    }

    @Override
    protected void initView() {
        setNavTitle(R.string.select);

        initTimePicker();
    }

    @OnClick({R.id.button6})
    public void clicked(View view) {
        switch (view.getId()) {
            case R.id.button6:
                pvTime.show();
                break;
        }
    }

    private void initTimePicker() {//Dialog 模式下,在底部弹出
        Calendar startDate = Calendar.getInstance();
        startDate.set(2019, 1, 1);
        Calendar endDate = Calendar.getInstance();
        endDate.set(2040, 1, 1);
        pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
            @Override
            public void onTimeSelect(Date date, View v) {
//                showErr(getTime(date));
                tvTime.setText(getTime(date));

            }
        })
                .setTimeSelectChangeListener(new OnTimeSelectChangeListener() {
                    @Override
                    public void onTimeSelectChanged(Date date) {
                        Log.i("pvTime", "onTimeSelectChanged");
                    }
                })
                .setType(new boolean[]{true, true, true, true, true, false})
                .isDialog(true) //默认设置false ,内部实现将DecorView 作为它的父控件。
                .addOnCancelClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Log.i("pvTime", "onCancelClickListener");
                    }
                })
                .setLayoutRes(R.layout.pickerview_custom_time, new CustomListener() {

                    @Override
                    public void customLayout(View v) {
                        final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish);
                        TextView ivCancel = (TextView) v.findViewById(R.id.iv_cancel);
                        tvSubmit.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                pvTime.returnData();
                                pvTime.dismiss();
                            }
                        });
                        ivCancel.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                pvTime.dismiss();
                            }
                        });
                    }
                })
                .setContentTextSize(18)
                .setDividerColor(Color.BLACK)
                .setRangDate(startDate, endDate)//起始终止年月日设定
                .build();

        Dialog mDialog = pvTime.getDialog();
        if (mDialog != null) {

            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    Gravity.BOTTOM);

            params.leftMargin = 0;
            params.rightMargin = 0;
            pvTime.getDialogContainerLayout().setLayoutParams(params);

            Window dialogWindow = mDialog.getWindow();
            if (dialogWindow != null) {
                dialogWindow.setWindowAnimations(com.bigkoo.pickerview.R.style.picker_view_slide_anim);//修改动画样式
                dialogWindow.setGravity(Gravity.BOTTOM);//改成Bottom,底部显示
                dialogWindow.setDimAmount(0.1f);
            }
        }
    }

    private String getTime(Date date) {//可根据需要自行截取数据显示
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(date);
    }
}