国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Android自定義滾動式時間選擇器(在他人基礎(chǔ)上修改)

陳江龍 / 2205人閱讀

摘要:但是如果用戶先確定了日,再去選擇月的話,之后月份改變,日數(shù)就會重新從開始。

盡管Android給我們提供了時間選擇控件DatePicker和TimePicker(它們的使用方法可以參考我的這篇文章Android之日期時間選擇控件DatePicker和TimePicker),但無奈我的項目主色調(diào)是土豪金和高級黑,原生的控件用在里面顯得格格不入,特別是為了兼容低版本的系統(tǒng)之后顯示的是2.x年代的風格,不但是簡陋,簡直是丑陋了。要解決這種問題,就只有走自定義控件這條道。但我目前還是不太熟悉自定義控件的寫法,所以只好發(fā)揮拿來主義了。查看了一通之后,發(fā)現(xiàn)liuwan1992這位博主寫的非常漂亮,我在他的基礎(chǔ)上做了一些改動,使得整個控件更符合我的項目。

這是他的文章鏈接:Android 好看的自定義滾動式日期選擇控件 ,關(guān)于控件的使用大家直接閱讀他的文章即可。在此,感謝他的付出,本人只是巨人肩膀上的小白而已。

1、創(chuàng)建工程

你可以下載博主的源碼,用Android Studio打開之后就直接動手修改,也可以像我這樣新建一個工程,然后將需要用到的代碼和文件從源碼復制過來即可。

2、修改對話框外觀

由于我需要用到我自己的顏色,所以在colors.xml中做了一些改動:


    #3F51B5
    #303F9F
    #FF4081
    
    #F0F0F0 //年、月、日等單位的字體顏色
    #FFFFFF
    #B0B0B0 //未被選中的數(shù)字顏色
    #666666
    #57C5E8
    #b0000000 //作為背景的高級黑
    #ffda53 //作為字體的土豪金

其中color_bg和color_gold分別是背景高級黑和字體土豪金。

資源文件準備好之后,就可以到對話框的布局custom_date_picker.xml中修改背景和字體顏色了。滾輪中選中和未選中的字體顏色則需要到DatePickerView中修改:

    private void init() {
        timer = new Timer();
        mDataList = new ArrayList<>();
        //第一個paint
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Style.FILL);
        mPaint.setTextAlign(Align.CENTER);
        //被選中的數(shù)字顏色
        mPaint.setColor(ContextCompat.getColor(context, R.color.color_gold));
        //第二個paint
        nPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        nPaint.setStyle(Style.FILL);
        nPaint.setTextAlign(Align.CENTER);
        //未選中的數(shù)字顏色
        nPaint.setColor(ContextCompat.getColor(context, R.color.color_text_unselected));
    }

修改完的效果如下,項目需求如此,如果覺得辣眼睛的請多多諒解。

3、給控件增加標題

雖然選擇的都是時間,但是如果我們在控件的標題中告訴用戶當前要選擇的是什么時間的話就更好一點。比如用戶要確定一個時間段的話,我們就可以在彈出的控件上顯示要選擇的是“起始時間”還是“結(jié)束時間”。因此,我們可以在CustomDatePicker的構(gòu)造函數(shù)中再增加一個參數(shù):

   public CustomDatePicker(Context context,String title, ResultHandler resultHandler, String startDate, String endDate) {
    }

這樣在創(chuàng)建控件時我們就可以把控件的標題傳進去了。

4、點擊控件以外的區(qū)域讓控件消失

這個修改比較簡單,我們的時間選擇控件其實就是一個Dialog,只要將setCancelable方法設置為true就可以了。

5、修改選擇順序

這個控件的時間選擇順序默認是“年-月-日-時-分”,也就是選好了年才能選擇月,選好了月才能選擇日,從左到右。但是如果用戶先確定了日,再去選擇月的話,之后月份改變,日數(shù)就會重新從1開始。用戶體驗無疑是十分糟糕的,所以我們要把用戶的每一步選擇都保存下來,使控件可以從右到左選擇時間。毫無疑問,這就需要到CustomDatePicker中改動了,因此,這一步的修改是最復雜也是最關(guān)鍵的。

5.1 保存用戶選好的時間數(shù)據(jù)

打開CustomDatePicker文件,創(chuàng)建以下幾個String變量:

    private String currentMon, currentDay, currentHour, currentMin; //當前選中的月、日、時、分

年份位于最左端,“權(quán)限”是最高的,不會受其它數(shù)據(jù)的影響,可以不必保存。仔細想想,我們需要在兩種情況下保存選中的日期數(shù)據(jù):

用戶滑動滾輪之后,保存選擇的數(shù)據(jù);

用戶沒有滑動滾輪,但是點擊了對話框上的“確認”按鈕

源碼中,對于每個滾輪的滾動都寫了監(jiān)聽方法,我們可以在每個監(jiān)聽方法中賦值:

   private void addListener() {
        year_pv.setOnSelectListener(new DatePickerView.onSelectListener() {
            @Override
            public void onSelect(String text) {
                selectedCalender.set(Calendar.YEAR, Integer.parseInt(text));
                monthChange();
            }
        });

        month_pv.setOnSelectListener(new DatePickerView.onSelectListener() {
            @Override
            public void onSelect(String text) {
                selectedCalender.set(Calendar.DAY_OF_MONTH, 1);
                selectedCalender.set(Calendar.MONTH, Integer.parseInt(text) - 1);
                currentMon = text; //保存選擇的月份
                dayChange();
            }
        });

        day_pv.setOnSelectListener(new DatePickerView.onSelectListener() {
            @Override
            public void onSelect(String text) {
                selectedCalender.set(Calendar.DAY_OF_MONTH, Integer.parseInt(text));
                currentDay = text;//保存選擇的日期
                hourChange();
            }
        });

        hour_pv.setOnSelectListener(new DatePickerView.onSelectListener() {
            @Override
            public void onSelect(String text) {
                selectedCalender.set(Calendar.HOUR_OF_DAY, Integer.parseInt(text));
                currentHour = text; //保存選擇的小時
                minuteChange();
            }
        });

        minute_pv.setOnSelectListener(new DatePickerView.onSelectListener() {
            @Override
            public void onSelect(String text) {
                selectedCalender.set(Calendar.MINUTE, Integer.parseInt(text));
                currentMin = text; //保存選擇的分鐘
            }
        });
    }

如果用戶沒有滑動滾輪,那么滾動監(jiān)聽事件就不會觸發(fā),這時就要到設置默認選中時間的方法setSelectedTime方法中去賦值了,比如分鐘的賦值:

currentMin = timeStr[1]; //保存選擇的分鐘

其它的時間數(shù)據(jù)同理,代碼太長,這里就不貼了,大家直接看Demo吧。

5.2 時間數(shù)據(jù)之間的聯(lián)動邏輯

保存好數(shù)據(jù)之后還沒有完,要知道,各個時間數(shù)據(jù)之間并不是可以任意選擇的,它們之間是相互關(guān)聯(lián),相互制約的,特別是當你規(guī)定了最大時間不超過當前時間時。比如假設現(xiàn)在是2017年05月24日15:30,當我滑到2017年5月23日16:00,此時再將日改回24日時,時間顯然是不能超過15:30的。這時就要做一些判斷了。

以分鐘的數(shù)值為例,如果當前的分鐘數(shù)值小于60,而且之前選擇的分鐘數(shù)值比當前的分鐘數(shù)值大,那么就要將分鐘數(shù)值修改為當前的分鐘時間,否則繼續(xù)沿用之前的數(shù)值。
閱讀源碼可以看到,修改分鐘數(shù)值的方法為minuteChange,將復位處理的代碼注釋之后,然后加上我們的邏輯判斷。

//            selectedCalender.set(Calendar.MINUTE, Integer.parseInt(minute.get(0)));
//            minute_pv.setSelected(0);
            if (minute.size() < 60 && minute.size() < Integer.valueOf(currentMin)) {
                minute_pv.setSelected(minute.size() - 1);
                selectedCalender.set(Calendar.MINUTE, minute.size());
                //改變當前選擇的分鐘
                currentMin = formatTimeUnit(minute.size());
            } else {
                minute_pv.setSelected(currentMin);
                selectedCalender.set(Calendar.MINUTE, Integer.parseInt(currentMin));
            }

小時的判斷跟分鐘的差不多,這里就貼代碼了,但是月份的就有點特殊了,因為無論哪一天都是24小時,無論哪一小時都有60分鐘,而每個月的天數(shù)卻不盡相同,比如二月份就只有28或者29天。我們需要再創(chuàng)建一個int值變量lastMonthDays來記錄上一個被選中的月份的天數(shù)。當前選中的月份天數(shù)比之前選中的月份天數(shù)少,而且之前選中的日的數(shù)值比當前選中的月份天數(shù)還有大時,那么日的數(shù)值就必須改為這個月的最后一天了。舉個例子,比如將2017年3月31日中月份改為2月份,由于二月份只有28天,那么日的數(shù)值就不能停留在31了,而是跳轉(zhuǎn)到28。

dayChange方法中的代碼修改如下:

//        selectedCalender.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day.get(0)));
//        day_pv.setSelected(0);
        if (day.size() < lastMonthDays && Integer.valueOf(currentDay) > day.size()) {
            day_pv.setSelected(day.size() - 1);
            currentDay = formatTimeUnit(day.size());
        } else {
            day_pv.setSelected(currentDay);
        }
        selectedCalender.set(Calendar.DAY_OF_MONTH, Integer.parseInt(currentDay));
        //重新賦值
        lastMonthDays = day.size();

最后,當然也別忘了到setSelectedTime中給lastMonthDays設置默認值。

            lastMonthDays = day.size();
6、將某一列的數(shù)值設為多帶帶循環(huán)滾動

盡管源碼中已經(jīng)有setIsLoop方法可以設置為循環(huán)滾動,但是這個是將所有列都同時設置為循環(huán)滾動的,如果我們想多帶帶將某一列設為循環(huán)滾動的話可以再增加幾個方法:

    public void setYearIsLoop(boolean isLoop) {
        if (canAccess) {
            this.year_pv.setIsLoop(isLoop);
        }
    }

    public void setMonIsLoop(boolean isLoop) {
        if (canAccess) {
            this.month_pv.setIsLoop(isLoop);
        }
    }

    public void setDayIsLoop(boolean isLoop) {
        if (canAccess) {
            this.day_pv.setIsLoop(isLoop);
        }
    }

    public void setHourIsLoop(boolean isLoop) {
        if (canAccess) {
            this.hour_pv.setIsLoop(isLoop);
        }
    }

    public void setMinIsLoop(boolean isLoop) {
        if (canAccess) {
            this.minute_pv.setIsLoop(isLoop);
        }
    }
7、去除對話框與屏幕之間的間距

這個問題我在Demo中沒有發(fā)現(xiàn),整合到工程中才遇到。彈出對話框時,左右和底部有一定的間距始終消除不了,但是在初始化對話框的方法initDialog方法中加了下面的代碼就可以了:

      window.setBackgroundDrawableResource(R.color.color_bg);

顏色的值可以是透明的,但個人覺得最后還是設置一個背景色。這個問題,目前我也沒有找到原因……

8、總結(jié)

經(jīng)過上面一番改動,我可以愉快地整合到我自己的項目中了,個人覺得這個控件挺美觀實用的,歡迎大家支持原博主。如果大家有什么好的改動,也歡迎給我留言。下面附上源碼:

TimePickerDemo

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/67123.html

相關(guān)文章

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<