java 时间选择器,NumberPicker风格,2列,日期带今天,明天,星期,时间间隔30分钟

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 时间选择器,NumberPicker风格,2列,日期带今天,明天,星期,时间间隔30分钟相关的知识,希望对你有一定的参考价值。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="用车时间"
        android:textColor="@color/colorPrimary"
        android:textSize="18sp" />

    <LinearLayout
        android:layout_width="280dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginTop="20dp"
        android:orientation="horizontal">

        <com.wenmin92.test.datetimepicker.NumberPickerView
            android:id="@+id/picker_date"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            app:npv_ItemPaddingHorizontal="5dp"
            app:npv_ItemPaddingVertical="5dp"
            app:npv_ShowCount="5"
            app:npv_TextSizeNormal="18sp"
            app:npv_TextSizeSelected="20sp"
            app:npv_WrapSelectorWheel="false" />

        <com.wenmin92.test.datetimepicker.NumberPickerView
            android:id="@+id/picker_hour"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginStart="5dp"
            android:layout_weight="1"
            app:npv_ItemPaddingHorizontal="2dp"
            app:npv_ItemPaddingVertical="5dp"
            app:npv_RespondChangeInMainThread="false"
            app:npv_ShowCount="5"
            app:npv_TextSizeNormal="18sp"
            app:npv_TextSizeSelected="20sp"
            app:npv_WrapSelectorWheel="true" />

        <com.wenmin92.test.datetimepicker.NumberPickerView
            android:id="@+id/picker_minute"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginStart="5dp"
            android:layout_weight="1"
            app:npv_ItemPaddingHorizontal="2dp"
            app:npv_ItemPaddingVertical="5dp"
            app:npv_ShowCount="5"
            app:npv_TextSizeNormal="18sp"
            app:npv_TextSizeSelected="20sp"
            app:npv_WrapSelectorWheel="false" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp">

        <Button
            android:id="@+id/tv_cancel"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="取\t\t消" />

        <Button
            android:id="@+id/tv_confirm"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_marginLeft="10dp"
            android:layout_marginStart="10dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="确\t\t定" />
    </LinearLayout>

</LinearLayout>
package com.wenmin92.test.datetimepicker;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.wenmin92.test.R;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * Created by wenmin92 on 2018/1/19.
 * 时间选择器,NumberPicker 风格,2列,日期带今天、明天、星期,时间间隔30分钟
 *
 * @see <a href="https://github.com/Carbs0126/NumberPickerView">NumberPickerView</a>
 */
public class DateTime2InrPicker extends DialogFragment {

    private OnConfirmListener mOnConfirmListener;
    private SimpleDateFormat mDateFormat = new SimpleDateFormat("MM月dd日EEE", Locale.CHINA);
    private SimpleDateFormat mTimeFormat = new SimpleDateFormat("HH:mm", Locale.CHINA);
    private SimpleDateFormat mDateTimeFormat = new SimpleDateFormat("MM月dd日HH:mm", Locale.CHINA);
    private String[] mTimes;
    private String mSelectedTime = "00:00";
    private String mSelectedDate;

    @SuppressWarnings("SameParameterValue")
    public static DateTime2InrPicker newInstance(String title, OnConfirmListener onConfirmListener) {
        DateTime2InrPicker picker = new DateTime2InrPicker();
        Bundle args = new Bundle();
        args.putString("title", title);
        picker.setArguments(args);
        picker.setOnConfirmListener(onConfirmListener);
        return picker;
    }

    @SuppressLint("InflateParams")
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_date_time, null);
        final NumberPickerView pickerDate = (NumberPickerView) view.findViewById(R.id.picker_date);
        final NumberPickerView pickerHour = (NumberPickerView) view.findViewById(R.id.picker_hour);
        final TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);
        view.findViewById(R.id.picker_minute).setVisibility(View.GONE);
        tvTitle.setText(getArguments().getString("title"));

        // 按钮点击事件
        view.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
        view.findViewById(R.id.tv_confirm).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
                Date date;
                try {
                    date = mDateTimeFormat.parse(mSelectedDate.substring(0, 6) + mSelectedTime);
                    Calendar calendar = Calendar.getInstance();
                    int year = calendar.get(Calendar.YEAR);
                    calendar.setTime(date);
                    calendar.set(Calendar.YEAR, year);
                    date = calendar.getTime();
                    if (date.before(new Date())) {
                        Toast.makeText(getActivity(), "所选时间无效,请选择当前时间之后的时间", Toast.LENGTH_SHORT).show();
                        return;
                    }
                } catch (ParseException e) {
                    Toast.makeText(getActivity(), "请选择一个时间", Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                    return;
                }
                mOnConfirmListener.onConfirmed(date);
            }
        });

        // 日期
        String[] dates = getDates();
        pickerDate.refreshByNewDisplayedValues(dates);
        pickerHour.setWrapSelectorWheel(false);
        pickerDate.setOnValueChangedListener(new NumberPickerView.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPickerView picker, int oldVal, int newVal) {
                pickerHour.refreshByNewDisplayedValues(getTimes(picker.getValue() == 0));
                int index = Arrays.binarySearch(mTimes, mSelectedTime);
                pickerHour.setValue(index == -1 ? 0 : index);
                if (index == -1) mSelectedTime = mTimes[0];
                mSelectedDate = picker.getContentByCurrValue();
            }
        });

        // 时间
        pickerHour.refreshByNewDisplayedValues(getTimes(true));
        pickerHour.setWrapSelectorWheel(false);
        pickerHour.setOnValueChangedListener(new NumberPickerView.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPickerView picker, int oldVal, int newVal) {
                mSelectedTime = picker.getContentByCurrValue();
                // Log.d("DateTime2InrPicker", picker.getContentByCurrValue());
            }
        });

        builder.setView(view);
        mSelectedDate = dates[0];
        mSelectedTime = mTimes[0];
        return builder.create();
    }

    /**
     * 获取日期,默认15天
     */
    private String[] getDates() {
        // 注意边界时间
        String[] dates = new String[15];
        Calendar calendar = Calendar.getInstance();
        if (calendar.get(Calendar.HOUR_OF_DAY) >= 23 && calendar.get(Calendar.MINUTE) > 30) {
            calendar.add(Calendar.HOUR_OF_DAY, 1);
        }

        // 获取日期序列
        for (int i = 0; i < dates.length; i++) {
            dates[i] = mDateFormat.format(calendar.getTime());
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }
        dates[0] = dates[0].substring(0, 6) + "今天";
        dates[1] = dates[1].substring(0, 6) + "明天";
        // Log.d("DateTime2InrPicker", "times:" + Arrays.toString(dates));
        return dates;
    }

    private String[] mFullTimes;

    private String[] getTimes(boolean isToday) {
        // 注意边界时间
        // 因为都一样,所以无需计算,直接使用计算过的
        if (isToday && mFullTimes != null && mFullTimes.length == 24) {
            return mFullTimes;
        }

        // 初始化
        Calendar calendar = Calendar.getInstance();
        int amount;
        if (isToday) { // 当天时间不完整,只取剩余时间
            if (calendar.get(Calendar.MINUTE) >= 30) {
                calendar.add(Calendar.HOUR_OF_DAY, 1);
                calendar.set(Calendar.MINUTE, 0);
                amount = (24 - calendar.get(Calendar.HOUR_OF_DAY) - 1) * 2;
                if (calendar.get(Calendar.HOUR_OF_DAY) == 23) amount = 24 * 2;
            } else {
                calendar.set(Calendar.MINUTE, 30);
                amount = (24 - calendar.get(Calendar.HOUR_OF_DAY)) * 2 - 1;
            }
        } else { // 非当天可取任意时间
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            amount = 24 * 2;
        }

        // 获取时间序列
        String[] times = new String[amount];
        for (int i = 0; i < times.length; i++) {
            times[i] = mTimeFormat.format(calendar.getTime());
            calendar.add(Calendar.MINUTE, 30);
        }

        mTimes = times;
        // 缓存完整时间序列
        if (!isToday) mFullTimes = times;
        // Log.d("DateTime2InrPicker", "times:" + Arrays.toString(times));
        return times;
    }

    public void setOnConfirmListener(OnConfirmListener onConfirmListener) {
        this.mOnConfirmListener = onConfirmListener;
    }

    public interface OnConfirmListener {
        void onConfirmed(Date date);
    }
}

以上是关于java 时间选择器,NumberPicker风格,2列,日期带今天,明天,星期,时间间隔30分钟的主要内容,如果未能解决你的问题,请参考以下文章

Android零基础入门第58节:数值选择器NumberPicker

android选择器隐藏上下值

NumberPicker 在 setValue() 之后显示错误的值

Android Numberpicker 小数

如何更改android中的数字选择器样式?

在 Android 中将 OnValueChange 实现为 NumberPicker