天天看點

TimePickerDialog樣式配置與TimePicker模式選擇

習慣性的,把要說的内容先總結一下:

TimePicker有兩種模式:spinner 和clock,可通過如下方式配置:

<TimePicker
        android:timePickerMode = "spinner"
           
android:layout_width="match_parent"
        android:layout_height="match_parent">
    </TimePicker>
           

或者

android:timePickerMode = "clock"
           

這兩種模式對應的時間的選擇一個是模拟的Clock,一個是類似spinner的方式。

另一個内容是TimePickerDialog的樣式。TimePickerDialog可以配置很多種樣式,可以直接在構造函數中來配置。代碼如下:

timePickerDialog = new TimePickerDialog(this, android.R.style.Theme_DeviceDefault_Light_Dialog,new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

            }
        },0,0,false);
        timePickerDialog.setTitle("pick");
        timePickerDialog.show();
           

也可以不明确指定樣式,把上面構造函數的第二個參數去掉就好了。這裡,我看到很多代碼都沒有第二個參數,是以這裡把它提出來。

是以,以上就是我要說的所有内容。那麼這麼簡單的東西,我為什麼要把它專門寫一篇部落格呢?原因是這樣的:

Android5.0的時候,我使用TimePickerDialog時,外觀是這樣的:

TimePickerDialog樣式配置與TimePicker模式選擇

而到了android6.0的時候,同樣的代碼,TimePickerDialog的樣式是這樣的:

TimePickerDialog樣式配置與TimePicker模式選擇

這讓我很詫異,我嘗試在系統源碼中尋找答案。TimePickerDialog的源碼在:frameworks\base\core\java\android\app下,源碼很簡單,我就不貼出來了,TimePickerDialog中使用了TimePicker,TimePicker的源碼在:frameworks\base\core\java\android\widget。在其構造函數中:

public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        final TypedArray a = context.obtainStyledAttributes(
                attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
        final int mode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER);
        a.recycle();
        switch (mode) {
            case MODE_CLOCK:
                mDelegate = new TimePickerClockDelegate(
                        this, context, attrs, defStyleAttr, defStyleRes);
                break;
            case MODE_SPINNER:
            default:
                mDelegate = new TimePickerSpinnerDelegate(
                        this, context, attrs, defStyleAttr, defStyleRes);
                break;
        }
    }
           

可以看到TimePicker有兩種模式: MODE_CLOCK和 MODE_SPINNER。我猜想我需要的是spinner,是以我就在這裡強制把mode配置為MODE_SPINNER,然後更新完系統Jar包後發現果不其然,這個時候TimePickerDialog變成了這樣:

TimePickerDialog樣式配置與TimePicker模式選擇

這時候可以看到明顯變了一種模式,但是這種模式還不是我想要的,于是我百度TimePickerDialog主題配置,但令我失望的是并沒有找到相關的内容,于是我嘗試配置 TimePickerDialog構造函數的第二個樣式,也就是給TimePickerDialog指定特定的Theme,果然,每次指定完後發現TimePickerDialog的樣子都有變化,當我把它配置為

android.R.style.Theme_DeviceDefault_Light_Dialog時,我想要的效果出現了,也就是開始的第一張照片所展示的樣式。這個時候,回過頭來,很明顯在代碼中給TimePickerm
           
指定特定的樣式不是明智的選擇,通過檢視源碼發現TimePicker的構造函數中擷取mode的方式是:
           
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
final int mode = a.getInt(R.styleable.TimePicker_timePickerMode, MODE_SPINNER);
           
從這裡可以看出可以看到系統給TimerPicker自定義了屬性:timePickerMode,如果這裡看不明白,可以百度下view自定義屬性試試。然後在res/value/attr.xml檔案中搜尋該變量,可以看到:
           
<span style="font-family: 'Times New Roman';"></span><pre name="code" class="html">        <attr name="timePickerMode">
            <!-- Time picker with spinner controls to select the time. -->
            <enum name="spinner" value="1" />
            <!-- Time picker with clock face to select the time. -->
            <enum name="clock" value="2" />
        </attr>
           

這意味着可以在xml檔案中給TimePicker指定特定的模式,就像文章開頭做的那樣。如此,就實作了自己想要的TimePickerDialog的樣式。

繼續閱讀