Android自定義時間控件不可選擇未來時間

本文出自:http://blog.csdn.net/dt235201314/article/details/78718066

Android自定義時間控件選擇開始時間到結束時間

Android自定義時間控件不可選擇未來時間

一丶效果圖

二丶概述

說好的關於時間控件整理,這裏就說說常用的自定義,關於基礎其他文章寫得太詳細了

基礎學習:

Java 日期時間

Date & Time組件(上)

Date & Time組件(下)

API在線文檔Data Calendar DateFormat

三丶需求分析

1.滑動選擇時間確定到日,不可選擇未來時間(年月日都不能超過當前月數)

2.自定義

通常涉及到時間控件,1.選擇時間,查詢數據;2選擇時間上報數據


四丶看代碼

1.DateSelectDialog.Java

public class DateSelectDialog extends Dialog implements OnClickListener {
    private Context mContext;

    /**
     * 事件選取完畢監聽
     */
    private OnDateSelectFinished onDateSelectFinished;
    /**
     * 確認
     */
    private Button mOk;
    /**
     * 返回
     */
    private Button mBack;
    /**
     * 開始、結束年份
     */
    private static int START_YEAR = 1990, END_YEAR = 2100;
    /**
     * 最大年齡
     */
    private final int LARGEST_AGE = 119;
    /**
     * 年
     */
    private WheelView mYearView;
    /**
     * 月
     */
    private WheelView mMonthView;
    /**
     * 日
     */
    private WheelView mDayView;
    /**
     * 時
     */
    private WheelView mHourView;
    /**
     * 分
     */
    private WheelView mMinuteView;
    /**
     * list列表(大月份)
     */
    private List<String> mListBig;
    /**
     * list列表(小月份)
     */
    private List<String> mListLittle;

    /* 是否只選擇本年 */
    private boolean isOnlyThisYear = false;

    private  boolean isShowMinute = false;
    /* 是否只選擇本月 */
    private boolean isOnlyThisMonth = false;

    public static final String YEAR = "year";
    public static final String MONTH = "month";
    public static final String DAY = "day";
    int year;
    int month;
    int day;
    int hour;
    int minute;

    int curYear;
    int curMonth;
    int curDay;

    boolean HourMinuteVisiable;

    /**
     * 是否只是顯示本年和本月的時間選擇器
     *
     * @param context              context
     * @param date                 傳入的時間 格式 2017-2-13
     * @param onDateSelectFinished onDateSelectFinished
     * @param isOnlyThisYear       isOnlyThisYear 是否只顯示本年
     * @param isOnlyThisMonth      isOnlyThisMonth 是否只顯示本月
     */
    public DateSelectDialog(Context context, String date, OnDateSelectFinished onDateSelectFinished, boolean isOnlyThisYear, boolean isOnlyThisMonth) {
        super(context, R.style.DialogTheme);
        setContentView(R.layout.date_layout);
        this.mContext = context;
        this.onDateSelectFinished = onDateSelectFinished;
        this.isOnlyThisYear = isOnlyThisYear;
        this.isOnlyThisMonth = isOnlyThisMonth;
        init(date, true);
    }

    /**
     * <br> </br>
     *
     * @param context
     */
    public DateSelectDialog(Context context, String date, OnDateSelectFinished onDateSelectFinished) {
        super(context, R.style.DialogTheme);
        setContentView(R.layout.date_layout);
        this.mContext = context;
        this.onDateSelectFinished = onDateSelectFinished;
        init(date, true);
    }

    public DateSelectDialog(Context context, String date, OnDateSelectFinished onDateSelectFinished, boolean isShowHour) {
        super(context, R.style.DialogTheme);
        setContentView(R.layout.date_layout);
        this.mContext = context;
        this.onDateSelectFinished = onDateSelectFinished;
        init(date, isShowHour);
    }

    private void init(String date, boolean isShowHour) {
        Calendar calendar = Calendar.getInstance();
        curYear = calendar.get(Calendar.YEAR);
        curMonth = calendar.get(Calendar.MONTH) + 1;
        curDay = calendar.get(Calendar.DATE);
        hour = calendar.get(Calendar.HOUR_OF_DAY);
        minute = calendar.get(Calendar.MINUTE);

        String[] ymd = date.split("-");
        if (ymd.length > 2) {
            curYear = Integer.parseInt(ymd[0]);
            curMonth = Integer.parseInt(ymd[1]) - 1;
            String[] dhm = ymd[2].split(" ");
            curDay = Integer.parseInt(dhm[0]);
            if (dhm != null && dhm.length > 1) {
                String[] hm = dhm[1].split(":");
                if (hm.length > 1) {
                    hour = Integer.parseInt(hm[0]);
                    minute = Integer.parseInt(hm[1]);
                }
            }
        }

        mOk = (Button) findViewById(R.id.btn_datetime_ok);
        mBack = (Button) findViewById(R.id.btn_datetime_cancel);
        mYearView = (WheelView) findViewById(R.id.year);
        mMonthView = (WheelView) findViewById(R.id.month);
        mDayView = (WheelView) findViewById(R.id.day);
        mHourView = (WheelView) findViewById(R.id.hour);
        mMinuteView = (WheelView) findViewById(R.id.minute);

        if (!isShowHour) {
            mHourView.setVisibility(View.GONE);
            mMinuteView.setVisibility(View.GONE);
        }

        if (!isShowMinute) {
            mMinuteView.setVisibility(View.GONE);
        }

        /* 年,月,日,時,分 等單位,和值同在 */
        TextView tv_yearUnit = (TextView) findViewById(R.id.tv_yearUnit);
        tv_yearUnit.setVisibility(mYearView.getVisibility());
        TextView tv_monthUnit = (TextView) findViewById(R.id.tv_monthUnit);
        tv_monthUnit.setVisibility(mMonthView.getVisibility());
        TextView tv_dayUnit = (TextView) findViewById(R.id.tv_dayUnit);
        tv_dayUnit.setVisibility(mDayView.getVisibility());
        TextView tv_hourUnit = (TextView) findViewById(R.id.tv_hourUnit);
        tv_hourUnit.setVisibility(mHourView.getVisibility());
        TextView tv_minuteUnit = (TextView) findViewById(R.id.tv_minuteUnit);
        tv_minuteUnit.setVisibility(mMinuteView.getVisibility());
        mOk.setOnClickListener(this);
        mBack.setOnClickListener(this);
        initDatePicker();
        mYearView.addChangingListener(yearWheelListener);
        mMonthView.addChangingListener(monthWheelListener);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_datetime_ok:
                if (onDateSelectFinished != null) {
                    int hour = mHourView.getCurrentItem();
                    int minute = mMinuteView.getCurrentItem();
                    int year = isOnlyThisYear ? Integer.parseInt(mYearView.getAdapter().getItem(0))
                            : mYearView.getCurrentItem() + START_YEAR;
                    int month = isOnlyThisMonth ? Integer.parseInt(mMonthView.getAdapter().getItem(0))
                            : mMonthView.getCurrentItem() + 1;
                    int day = mDayView.getCurrentItem() + 1;
                    String monthS = String.format("%02d", month);
                    String dayS = String.format("%02d", day);
                    String hourS = String.format("%02d", hour);
                    String minuteS = String.format("%02d", minute);
                    onDateSelectFinished.onSelectFinished(String.valueOf(year), monthS, dayS, hourS, minuteS);
                }
                this.dismiss();
                break;
            case R.id.btn_datetime_cancel:
                this.dismiss();
                break;
            default:
                break;
        }

    }

    /**
     * 彈出日期時間選擇器
     */
    private void initDatePicker() {
        Calendar calendar = Calendar.getInstance();
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DATE);
        START_YEAR = isOnlyThisYear ? year : year - LARGEST_AGE;
        END_YEAR = year;

        // 添加大小月月份並將其轉換爲list,方便之後的判斷
        String[] monthsBig = {"1", "3", "5", "7", "8", "10", "12"};
        String[] monthsLittle = {"4", "6", "9", "11"};

        mListBig = Arrays.asList(monthsBig);
        mListLittle = Arrays.asList(monthsLittle);

        // 年
        mYearView.setAdapter(new NumericWheelAdapter(START_YEAR, END_YEAR));// 設置"年"的顯示數據
        mYearView.setLabel("");// 添加文字
        int yearPos = isOnlyThisYear ? END_YEAR - START_YEAR : curYear != 0 ? curYear - START_YEAR : END_YEAR - START_YEAR;
        mYearView.setCurrentItem(yearPos);// 初始化時顯示的數據 START_YEAR - END_YEAR
        mYearView.setCyclic(!isOnlyThisYear);// 可循環滾動

        // 月
        int startMonth = 1, endMonth = 12;
        if (isOnlyThisMonth) {
            startMonth = curMonth + 1;
            endMonth = startMonth;
        }

        //初始年份最大值應該是當年最大月
        mMonthView.setAdapter(new NumericWheelAdapter(startMonth, month + 1));
//        mMonthView.setAdapter(new NumericWheelAdapter(startMonth, endMonth));
        mMonthView.setLabel("");
        mMonthView.setCurrentItem(isOnlyThisMonth ? 0 : curMonth != 0 ? curMonth : month);
        mMonthView.setCyclic(!isOnlyThisMonth);

        // 日
        // 判斷大小月及是否閏年,用來確定"日"的數據
        int deadDay = 0;
        if (mListBig.contains(String.valueOf(month + 1))) {
            deadDay = 31;
//            mDayView.setAdapter(new NumericWheelAdapter(1, isOnlyThisMonth ? day : 31));
        } else if (mListLittle.contains(String.valueOf(month + 1))) {
            deadDay = 30;
//            mDayView.setAdapter(new NumericWheelAdapter(1, isOnlyThisMonth ? day : 30));
        } else {
            // 閏年
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                deadDay = 29;
//                mDayView.setAdapter(new NumericWheelAdapter(1, isOnlyThisMonth ? day : 29));
            } else {
                deadDay = 28;
//                mDayView.setAdapter(new NumericWheelAdapter(1, isOnlyThisMonth ? day : 28));
            }
        }
        mDayView.setAdapter(new NumericWheelAdapter(1,day));
        mDayView.setLabel("");
        mDayView.setCurrentItem(curDay == 0 ? day - 1 : curDay - 1);
        mDayView.setCyclic(true);

        // 時
        mHourView.setAdapter(new NumericWheelAdapter(0, 23));
        mHourView.setLabel("");
        mHourView.setCurrentItem(hour);
        mHourView.setCyclic(true);

        // 分
        mMinuteView.setAdapter(new NumericWheelAdapter(0, 59));
        mMinuteView.setLabel("");
        mMinuteView.setCurrentItem(minute);
        mMinuteView.setCyclic(true);

        // 選擇器字體的大小
        int textSize = mContext.getResources().getDimensionPixelSize(R.dimen.ymd_text_size);
        mDayView.TEXT_SIZE = textSize;
        mMonthView.TEXT_SIZE = textSize;
        mYearView.TEXT_SIZE = textSize;
        mHourView.TEXT_SIZE = textSize;
        mMinuteView.TEXT_SIZE = textSize;
    }

    /**
     * 添加對"年"監聽
     */
    private OnWheelChangedListener yearWheelListener = new OnWheelChangedListener() {
        public void onChanged(WheelView wheel, int oldValue, int newValue) {
            int year_num = newValue + START_YEAR;
            if (year_num < curYear) {
                mMonthView.setAdapter(new NumericWheelAdapter(1, 12));
            } else if (year_num >= curYear) {
                mMonthView.setAdapter(new NumericWheelAdapter(1, curMonth + 1));
            }
            mMonthView.setCurrentItem(0);
            // 判斷大小月及是否閏年,用來確定"日"的數據
            if (mListBig.contains(String.valueOf(mMonthView.getCurrentItem() + 1))) {
                mDayView.setAdapter(new NumericWheelAdapter(1, 31));
            } else if (mListLittle.contains(String.valueOf(mMonthView.getCurrentItem() + 1))) {
                mDayView.setAdapter(new NumericWheelAdapter(1, 30));
            } else {
                if ((year_num % 4 == 0 && year_num % 100 != 0) || year_num % 400 == 0)
                    mDayView.setAdapter(new NumericWheelAdapter(1, 29));
                else
                    mDayView.setAdapter(new NumericWheelAdapter(1, 28));
            }
        }
    };

    /**
     * 添加對"月"監聽
     */
    private OnWheelChangedListener monthWheelListener = new OnWheelChangedListener() {
        public void onChanged(WheelView wheel, int oldValue, int newValue) {
            int month_num = newValue + 1;
            if (month_num == (month + 1)){
                mDayView.setAdapter(new NumericWheelAdapter(1, day));
            }else{
                // 判斷大小月及是否閏年,用來確定"日"的數據
                if (mListBig.contains(String.valueOf(month_num))) {
                    mDayView.setAdapter(new NumericWheelAdapter(1, 31));
                } else if (mListLittle.contains(String.valueOf(month_num))) {
                    mDayView.setAdapter(new NumericWheelAdapter(1, 30));
                } else {
                    if (((mYearView.getCurrentItem() + START_YEAR) % 4 == 0 && (mYearView.getCurrentItem() + START_YEAR) % 100 != 0)
                            || (mYearView.getCurrentItem() + START_YEAR) % 400 == 0)
                        mDayView.setAdapter(new NumericWheelAdapter(1, 29));
                    else
                        mDayView.setAdapter(new NumericWheelAdapter(1, 28));
                }
            }
        }
    };

    /**
     * set監聽
     *
     * @param onDateSelectFinished
     */
    public void setOnDateSelectFinished(OnDateSelectFinished onDateSelectFinished) {
        this.onDateSelectFinished = onDateSelectFinished;
    }

    /**
     * 監聽接口
     * DatePickerUI.java
     *
     * @author wangj
     * @version 1.0
     * @date 2013-1-23 下午1:28:24
     */
    public interface OnDateSelectFinished {
        /**
         * 監聽方法
         *
         * @param year
         * @param month
         * @param day
         * @param hour
         * @param minute
         */
        void onSelectFinished(String year, String month, String day, String hour, String minute);
    }

}

<style name="DialogTheme" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <!-- 邊框 -->
    <item name="android:windowIsFloating">true</item>
    <!-- 是否浮現在activity之上 -->
    <item name="android:windowIsTranslucent">true</item>
    <!-- 半透明 -->
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:background">@android:color/transparent</item>
    <item name="android:backgroundDimEnabled">true</item>
    <!-- 模糊 -->
</style>

layout

<?xml version="1.0" encoding="utf-8"?>
<com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.RoundedLinearLayout
    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="wrap_content"
    android:background="@drawable/shape_white"
    app:round="10dp">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#fff">

        <TextView
            android:id="@+id/tv_time_title"
            android:layout_width="fill_parent"
            android:layout_height="44dp"
            android:background="@color/white"
            android:gravity="center"
            android:paddingLeft="14dp"
            android:text="@string/query_time_select_title"
            android:textColor="@color/black"
            android:textSize="16sp" />

        <include
            android:id="@+id/data_time_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tv_time_title"
            android:layout_centerHorizontal="true"
            layout="@layout/data_time_layout"/>

        <LinearLayout
            android:visibility="gone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tv_time_title"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="12dp"
            android:layout_marginTop="12dp"
            android:orientation="horizontal">

            <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
                android:id="@+id/year"
                android:layout_width="92dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.2" />

            <TextView
                android:id="@+id/tv_yearUnit"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:text="年" />

            <View
                android:layout_width="1px"
                android:layout_height="fill_parent"
                android:background="#e8e8e8" />

            <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
                android:id="@+id/month"
                android:layout_width="92dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.2" />

            <TextView
                android:id="@+id/tv_monthUnit"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:text="月" />

            <View
                android:id="@+id/v_monthAndDay"
                android:layout_width="1px"
                android:layout_height="fill_parent"
                android:background="#e8e8e8" />

            <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
                android:id="@+id/day"
                android:layout_width="92dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.2" />

            <TextView
                android:id="@+id/tv_dayUnit"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:text="日" />

            <View
                android:id="@+id/v_dayAndHour"
                android:layout_width="1px"
                android:layout_height="fill_parent"
                android:background="#e8e8e8" />

            <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
                android:id="@+id/hour"
                android:layout_width="92dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.2" />

            <TextView
                android:id="@+id/tv_hourUnit"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:text="時" />

            <View
                android:id="@+id/v_dayAndMinute"
                android:layout_width="1px"
                android:layout_height="fill_parent"
                android:background="#e8e8e8" />

            <com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.WheelView
                android:id="@+id/minute"
                android:layout_width="92dp"
                android:layout_height="wrap_content"
                android:layout_weight="0.2" />

            <TextView
                android:id="@+id/tv_minuteUnit"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:text="分" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_below="@+id/data_time_id"
            android:layout_centerHorizontal="true"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:orientation="horizontal"
            android:paddingBottom="20dp">

            <Button
                android:id="@+id/btn_datetime_cancel"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@drawable/bg_but_cancel"
                android:padding="5dp"
                android:text="@string/cancel"
                android:textColor="@color/blue_bg"
                android:textSize="14sp" />

            <View
                android:layout_width="20dp"
                android:layout_height="wrap_content" />

            <Button
                android:id="@+id/btn_datetime_ok"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@drawable/bg_but_ensure"
                android:padding="5dp"
                android:text="@string/ok"
                android:textColor="@color/white"
                android:textSize="14sp" />
        </LinearLayout>
    </RelativeLayout>

</com.example.jinboy.codertodeveloperbytcler.java_demo.appdemo.ui.widget.RoundedLinearLayout>

Android WheelView 詳解

自定義圓角LinearLayout.java

public class RoundedLinearLayout extends LinearLayout {
    /***/
    private Path mClip;
    /**
     * 圓角
     */
    private float mRoundConner;

    /**
     * @param context
     * @param attrs
     */
    @SuppressLint("NewApi")
    public RoundedLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        int sdkVersion = android.os.Build.VERSION.SDK_INT;
        if (sdkVersion >= 11) {
            this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.roundConner);
        mRoundConner = typeArray.getDimension(R.styleable.roundConner_round, 0);
        typeArray.recycle();

    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mClip = new Path();
        RectF rect = new RectF(1, 1, w - 1, h - 1);
        if (mRoundConner == 0f) {
            mRoundConner = getResources().getDimensionPixelSize(R.dimen.round_radius);
        }
        mClip.addRoundRect(rect, mRoundConner, mRoundConner, Direction.CW);
    }

    /**
     * @param canvas
     */
    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();
        /*抗鋸齒*/
        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        canvas.clipPath(mClip);
        super.dispatchDraw(canvas);
        canvas.restore();
    }

}

使用方法:

/**
 * 選擇日期
 */
public void picTime() {

    if (!paramsStrTime.contains("-")) {
        Date date = new Date();
        long time = date.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        paramsStrTime = format.format(time);
    }

    DateSelectDialog dateSelectDialog = new DateSelectDialog(this, paramsStrTime, new DateSelectDialog.OnDateSelectFinished() {
        @Override
        public void onSelectFinished(String year, String month, String day, String hour, String minute) {
            paramsStrTime = year + "-" + month + "-" + day + " " + hour + ":" + minute;
            String selectedTime = year + "年" + month + "月" + day + "日 "
                    + hour + ":" + minute;
            uiButton2.setText(selectedTime);
        }
    }, false, false);
    dateSelectDialog.show();
}

五丶跪求關注下載源碼,200粉小目標
github開源代碼分享,原文鏈接見上文
源碼下載記得順便Star哦~

下載鏈接:https://github.com/JinBoy23520/CoderToDeveloperByTCLer


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章