編輯:關於android開發
雖然自己也看過很多的Android源碼,也看過很多別人寫的源碼分析,但是總覺得寫出來的東西並不能完全展現代碼作者所寫的東西或者自己看源碼的思維過程。(無法用言語形容)
這篇文章對常用的時間選擇器TimePicker源碼的總結,我可能不會從頭一步一步的分析源代碼,僅是我看完後的總結,當然也從中學習並應用後才有的總結。
spinner:
一、從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對相應的,沒有必要兩個都分析
二、再看TimePickerClockDelegate.java,
1.也是從構造方法看起,
在構造方法的中用一段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這段代碼,發現風格有點不一樣,可能是兩個人或者同一個人在不同的時間寫的,
//下面是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)為了擴展或者兼容,可以采用代理的模式,由代理完成具體的實現。
今天我用自己寫的一個Demo 和大家詳細介紹一個Android開發中遇到的一些常用系統控件的使用技
我的Android進階之旅------)Android自定義View實現帶數字的進度條(NumberProgressBar) 第一步、效果展示 圖1、藍色的進度條
Android-操作欄之圖標導航,android-導航 想實現圖標向上導航功能,步子分兩步走: 1.樣式上要改變-->圖標要變成可點擊的按鈕,並有一個向左的箭
Android 操作數據庫的框架——greenDAO的學習 greenDAO的使用 簡介 官網給出如下介紹: greenDAO是一個對象關系映射(ORM)的框架,能夠