TimePicker源碼學習-TimePicker的結構

  雖然本身也看過不少的Android源碼,也看過不少別人寫的源碼分析,可是總以爲寫出來的東西並不能徹底展示代碼做者所寫的東西或者本身看源碼的思惟過程。(沒法用言語形容)java

  這篇文章對經常使用的時間選擇器TimePicker源碼的總結,我可能不會從頭一步一步的分析源代碼,僅是我看完後的總結,固然也從中學習並應用後纔有的總結。android

  spinner: api

 

 

1、從TimePicker.java看起
  1.TimePicker繼承FrameLayout,代表TimePicker只是用於佈局而不是具體的繪製,具體的繪製view確定在另外的地方畫,而後再佈局到這個FrameLayout上面(這個很關鍵!爲何?) 
public class TimePicker extends FrameLayout{
    //......       
}

  2.首先從TimePicker構造方法看起源碼分析

  在這裏看到了MODE_CLOCK和MODE_SPINNER,分別是TimePicker的兩種形式(能夠在佈局中對timePickerMode屬性設置clockt或者spinner,本文針對api23,目前發現android4.0是隻有一種模式),一種對應TimePickerClockDelegate,另一種對應的是TimePickerSpinnerDelegate。要注意this就是TimePicker,而且TimePicker被傳進了mDelegate 的構造參數裏面去。能夠看到選擇時間器最後要在mDelegate中進行繪製並佈局在mDelegate 中。佈局

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;
    }
}

   下面咱們轉移到TimePickerClockDelegate,由於TimePickerSpinnerDelegate對相應的,沒有必要兩個都分析學習

2、再看TimePickerClockDelegate.java,this

  1.也是從構造方法看起,spa

  在構造方法的中用一段inflate代碼,用於對layout文件進行展開。能夠看出,layout內容展開到delegator裏面,而這個就是TimePicker!!這時咱們就知道爲何TimePicker是繼承FrameLayout的了,從上面能夠看到Timepicker構造的時候已經傳進來。代理

//下面是TimePickerClockDelegate.java的代碼:
final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout,
R.layout.time_picker_material);
final View mainView = inflater.inflate(layoutResourceId, delegator);

mHeaderView = mainView.findViewById(R.id.time_header);

  另外咱們能夠對比一下TimePickerClockDelegate和TimePickerSpinnerDelegate這段代碼,發現風格有點不同,多是兩我的或者同一我的在不一樣的時間寫的,blog

//下面是TimePickerSpinnerDelegate.java的:
final LayoutInflater inflater = LayoutInflater.from(mContext);
inflater.inflate(layoutResourceId, mDelegator, true);

// hour
mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour);

  2.如下我再彙總了TimePickerClockDelegate的成員變量,並造成TimePicker的類圖結構

  從中你能夠看到TimePicker用到的類的關係

  3.TimePickerClockDelegate是一個組合式的自定義view

  從TimePickerClockDelegate代碼你能夠看到他裏面沒有onDraw方法,說明他是一個組合式的自定義view

   

  再從類圖中看他的成員變量和timepicker中clock顯示模式能夠看出,錶盤是在RadialTimePickerView裏面畫的,即  

   RadialTimePickerVIew:時鐘式的時間選擇器中的錶盤,
      其餘TextView:顯示的小時數和分鐘數,上下午顯示等(看TimePickerCLockDelegate的成員變量就能夠知道)

 

 
  4.因此最後也是最重要的就是錶盤RadialTimePickerVIew的繪製,他裏面的知識或者思想能夠用在不少的地方。好比一個文字兩種顏色或背景色(其實就是用到了畫圖區域的補集和餘集知識)。
    

 

 

  總結:本文主要講述Android中的TimePicker類的代碼結構,代碼細節沒有太細的深究,從中能夠學到很多知識。

      1)好比若是一個自定義控件比較複雜,能夠把它分解,而後再組合成一個總體。

      2)爲了擴展或者兼容,能夠採用代理的模式,由代理完成具體的實現。

 

相關文章
相關標籤/搜索