WheelView 实现 日期和时间同时选择

项目需要,整理一个同时选择日期和时间的控件。
效果图:
WheelView 实现 日期和时间同时选择_第1张图片

这里直接写成一个Dialog类,便于集成到项目中。下面直接贴出主要实现代码 DateTimeDialog:

public class DateTimeDialog {

    private Context context;

    private Dialog dialog;
    private static int START_YEAR = 1990, END_YEAR = 2100;

    private DateTimeChange dateTimeChange;


    public DateTimeDialog(Context context) {
        this.context = context;
    }

    public void init(Calendar calendar) {

        if (calendar == null) {
            calendar = Calendar.getInstance();
        }

        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);

        // 添加大小月月份并将其转换为list,方便之后的判断
        String[] months_big = {"1", "3", "5", "7", "8", "10", "12"};
        String[] months_little = {"4", "6", "9", "11"};

        final List list_big = Arrays.asList(months_big);
        final List list_little = Arrays.asList(months_little);

        dialog = new Dialog(context);
        dialog.setTitle("请选择日期与时间");
        // 找到dialog的布局文件
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.time_layout, null);

        // 年
        final WheelView wv_year = (WheelView) view.findViewById(R.id.year);
        wv_year.setAdapter(new NumericWheelAdapter(START_YEAR, END_YEAR));// 设置"年"的显示数据
        wv_year.setCyclic(true);// 可循环滚动
        wv_year.setLabel("年");// 添加文字
        wv_year.setCurrentItem(year - START_YEAR);// 初始化时显示的数据

        // 月
        final WheelView wv_month = (WheelView) view.findViewById(R.id.month);
        wv_month.setAdapter(new NumericWheelAdapter(1, 12));
        wv_month.setCyclic(true);
        wv_month.setLabel("月");
        wv_month.setCurrentItem(month);

        // 日
        final WheelView wv_day = (WheelView) view.findViewById(R.id.day);
        wv_day.setCyclic(true);
        // 判断大小月及是否闰年,用来确定"日"的数据
        if (list_big.contains(String.valueOf(month + 1))) {
            wv_day.setAdapter(new NumericWheelAdapter(1, 31));
        } else if (list_little.contains(String.valueOf(month + 1))) {
            wv_day.setAdapter(new NumericWheelAdapter(1, 30));
        } else {
            // 闰年
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
                wv_day.setAdapter(new NumericWheelAdapter(1, 29));
            else
                wv_day.setAdapter(new NumericWheelAdapter(1, 28));
        }
        wv_day.setLabel("日");
        wv_day.setCurrentItem(day - 1);

        // 时
        final WheelView wv_hours = (WheelView) view.findViewById(R.id.hour);
        wv_hours.setAdapter(new NumericWheelAdapter(0, 23 , "%02d"));
        wv_hours.setCyclic(true);
        wv_hours.setCurrentItem(hour);

        // 分
        final WheelView wv_mins = (WheelView) view.findViewById(R.id.mins);
        wv_mins.setAdapter(new NumericWheelAdapter(0, 59, "%02d"));
        wv_mins.setCyclic(true);
        wv_mins.setCurrentItem(minute);

        // 添加"年"监听
        OnWheelChangedListener wheelListener_year = new OnWheelChangedListener() {
            public void onChanged(WheelView wheel, int oldValue, int newValue) {
                int year_num = newValue + START_YEAR;
                // 判断大小月及是否闰年,用来确定"日"的数据
                if (list_big.contains(String
                        .valueOf(wv_month.getCurrentItem() + 1))) {
                    wv_day.setAdapter(new NumericWheelAdapter(1, 31));
                } else if (list_little.contains(String.valueOf(wv_month
                        .getCurrentItem() + 1))) {
                    wv_day.setAdapter(new NumericWheelAdapter(1, 30));
                } else {
                    if ((year_num % 4 == 0 && year_num % 100 != 0)
                            || year_num % 400 == 0)
                        wv_day.setAdapter(new NumericWheelAdapter(1, 29));
                    else
                        wv_day.setAdapter(new NumericWheelAdapter(1, 28));
                }
            }
        };
        // 添加"月"监听
        OnWheelChangedListener wheelListener_month = new OnWheelChangedListener() {
            public void onChanged(WheelView wheel, int oldValue, int newValue) {
                int month_num = newValue + 1;
                // 判断大小月及是否闰年,用来确定"日"的数据
                if (list_big.contains(String.valueOf(month_num))) {
                    wv_day.setAdapter(new NumericWheelAdapter(1, 31));
                } else if (list_little.contains(String.valueOf(month_num))) {
                    wv_day.setAdapter(new NumericWheelAdapter(1, 30));
                } else {
                    if (((wv_year.getCurrentItem() + START_YEAR) % 4 == 0 && (wv_year
                            .getCurrentItem() + START_YEAR) % 100 != 0)
                            || (wv_year.getCurrentItem() + START_YEAR) % 400 == 0)
                        wv_day.setAdapter(new NumericWheelAdapter(1, 29));
                    else
                        wv_day.setAdapter(new NumericWheelAdapter(1, 28));
                }
            }
        };
        wv_year.addChangingListener(wheelListener_year);
        wv_month.addChangingListener(wheelListener_month);

        Button btn_sure = (Button) view.findViewById(R.id.btn_datetime_sure);
        Button btn_cancel = (Button) view
                .findViewById(R.id.btn_datetime_cancel);
        //确定
        btn_sure.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                // 如果是个数,则显示为"02"的样式
                String parten = "00";
                DecimalFormat decimal = new DecimalFormat(parten);
//              设置日期的显示
                String dateTime = (wv_year.getCurrentItem() + START_YEAR) + "-"
                        + decimal.format((wv_month.getCurrentItem() + 1)) + "-"
                        + decimal.format((wv_day.getCurrentItem() + 1)) + " "
                        + decimal.format(wv_hours.getCurrentItem()) + ":"
                        + decimal.format(wv_mins.getCurrentItem());


                Log.d("dateTime:", dateTime);

                dateTimeChange.onDateTimeChange(dateTime);

                dialog.dismiss();
            }
        });
        // 取消
        btn_cancel.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                dialog.dismiss();
            }
        });
        // 设置dialog的布局,并显示
        dialog.setContentView(view);
        dialog.show();

    }

    /**
     * @param dateTimeChanged
     */
    public void setOnDateTimeChanged(DateTimeChange dateTimeChanged) {
        this.dateTimeChange = dateTimeChanged;
    }

    /**
     * 用于回调输入选择的日期时间,可根据需要调整
     */
    public interface DateTimeChange {
        /**
         * @param dateTime yyyy-mm-dd HH24:mm 表示的日期时间字符串
         */
        public void onDateTimeChange(String dateTime);
    }
}

Dialog中写了一些注释,所以这里就不多解释了,下面是布局文件 time_layout:

"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/layout_bg">

    "@+id/timePicker1"
                  xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_centerHorizontal="true"
                  android:paddingLeft="12dp"
                  android:paddingRight="12dp"
                  android:paddingTop="10dp">

        <com.lvfq.datetime_selector_master.wheelview.WheelView
            android:id="@+id/year"
            android:layout_width="85dip"
            android:layout_height="wrap_content"/>

        <com.lvfq.datetime_selector_master.wheelview.WheelView
            android:id="@+id/month"
            android:layout_width="50dip"
            android:layout_height="wrap_content"/>

        <com.lvfq.datetime_selector_master.wheelview.WheelView
            android:id="@+id/day"
            android:layout_width="50dip"
            android:layout_height="wrap_content"/>

        <com.lvfq.datetime_selector_master.wheelview.WheelView
            android:id="@+id/hour"
            android:layout_width="44dip"
            android:layout_height="wrap_content"/>

        <com.lvfq.datetime_selector_master.wheelview.WheelView
            android:id="@+id/mins"
            android:layout_width="44dip"
            android:layout_height="wrap_content"/>
    

    "wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/timePicker1"
        android:layout_centerHorizontal="true"
        android:layout_centerInParent="true"
        android:layout_marginTop="12dp">

        

布局文件中可以根据自己项目需要,调整显示样式, 文字大小就直接在 WheelView 文件中设置了,

参考项目: https://github.com/iamchenney/DateTimePicker

如果当前效果不是你想要的,那么不要急,这里还有另一种效果 Android 高仿 IOS 滚轮组件

Demo下载

你可能感兴趣的:(Android)