編輯:關於Android編程
DialogFragment是Fragment家族成員之一,如果你把它簡單的理解成Dialog,那就錯了。它的確可以做作dialog顯示,還可以顯示出自己定義的Dialog或者AlertDialog,但它同時也是一個Fragment。
按照官方的話來理解就是,你既可以把它當成一個dialog顯示出來,也可以讓它作為一個Fragment嵌套在Activity中,這樣更方便開發。
為什麼這麼說呢?試想一下,當產品需求最開始把它作為一個界面顯示的時候,你可能已經把它作為Fragment已經寫好了,但中途產品又把它設計成一個dialog,那你該怎麼辦?重新去一個dialog或者activity嗎?以前的傳參怎麼辦?過兩天,產品又將它改回去,你還要再重寫一遍嗎?等等一系列的問題就來了。
所以,這個時候,你只需要把當前的Fragment繼承類改為DialogFragment,再添加幾行代碼就可以了。其他的,基本都不用動。即使過兩天再改回來,或者別的界面也需要它的時候,你就可以直接把它當做Fragment,繼續使用,代碼都不用改。
這一點,不得不贊一下Fragment這個的出現,大大方便了開發,再也不怕產品設計調整界面布局了!
這裡多啰嗦一句,如果產品已經定義好了作為dialog,或者之前就是dialog的,就不要將它們改成DialogFragment的了,還是那句話:只做有意義的代碼改動!
DialogFragment的使用用例,官方文檔已經寫得很清楚了,Demo例子也有,在androidSDK的sample文件夾中,有需要的請自行查閱。
今天之所以翻出源碼來,主要還是希望通過對代碼的了解,更好使用DialogFragment。而且有些細節部分,不看源碼的話,可能就真在方法傳值時傳錯了。比如:style的設置!
在源碼最開始部分,就定義了style的常量:
public static final int STYLE_NORMAL = 0; public static final int STYLE_NO_TITLE = 1; public static final int STYLE_NO_FRAME = 2; public static final int STYLE_NO_INPUT = 3;
STYLE_NORMAL:會顯示一個普通的dialog
STYLE_NO_TITLE:不帶標題的dialog
STYLE_NO_FRAME:無框的dialog
STYLE_NO_INPUT:無法輸入內容的dialog,即不接收輸入的焦點,而且觸摸無效。
說起來,android很多參數的設置,都有用到“|”的方法,表示支持兩種或兩種以上。最常見的,就是“Top|Left”,所以,在這裡有很多人會想用吧:STYLE_NO_TITLE|STYLE_NO_INPUT。那你可就錯了,這麼用的結果就是把style設置成了:STYLE_NO_INPUT ( 因為:1 | 3 = 3 )
接下來,再看一下它的內部變量:
int mStyle = STYLE_NORMAL; int mTheme = 0; boolean mCancelable = true; boolean mShowsDialog = true; int mBackStackId = -1; Dialog mDialog; boolean mViewDestroyed; boolean mDismissed; boolean mShownByMe;
mTheme:主題,默認沒有設置,而是在setStyle(int style, int theme) 方法中,對其初始化設置,下面會講到;
mCancelable:是否可以取消,默認是ture,實際上就是設置給Dialog的mDialog.setCancelable(mCancelable);
mShowsDialog:這個參數我放到下面去講,默認也為true
mBackStackId:後退棧的ID,也就是說,當DialogFragment不顯示時,會清空棧裡的數據。(關於後退棧的問題,請留心我後面關於FragmentManager詳解的文章);
mDialog:DialogFragment之所以會以窗口方式顯示,實際上就是其內部有一個Dialog,也就是它,上面的樣式、主題、可取消都是設置給它的;
後面三個boolean的變量,就是標志位:
mViewDestroyed:標志位,在Dialog不顯示時,處理Fragment的移除操作;
mDismissed:標志位,Dialog是否不顯示了;
mShownByMe:標志位,在Dialog是否顯示,和mDismissed基本是一對;
DialogFragment的構造方法是空的,什麼也沒有:
public DialogFragment() { }
public void setStyle(int style, int theme) { mStyle = style; if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) { mTheme = android.R.style.Theme_Panel; } if (theme != 0) { mTheme = theme; } }
這還可以根據自己定義的Dialog樣式設置進來。
下面就是show方法,共有兩個:
public void show(FragmentManager manager, String tag) { mDismissed = false; mShownByMe = true; FragmentTransaction ft = manager.beginTransaction(); ft.add(this, tag); ft.commit(); }
public int show(FragmentTransaction transaction, String tag) { mDismissed = false; mShownByMe = true; transaction.add(this, tag); mViewDestroyed = false; mBackStackId = transaction.commit(); return mBackStackId; }
有顯示,就是得有不顯示的代碼:
public void dismiss() { dismissInternal(false); }
public void dismissAllowingStateLoss() { dismissInternal(true); }
兩個方法都是調用了void dismissInternal(boolean allowStateLoss),只是傳參不一樣而已,看一下dismissInternal這個方法:
void dismissInternal(boolean allowStateLoss) { if (mDismissed) { return; } mDismissed = true; mShownByMe = false; if (mDialog != null) { mDialog.dismiss(); mDialog = null; } mViewDestroyed = true; if (mBackStackId >= 0) { getFragmentManager().popBackStack(mBackStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE); mBackStackId = -1; } else { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.remove(this); if (allowStateLoss) { ft.commitAllowingStateLoss(); } else { ft.commit(); } } }
1、調用dialog的dismiss方法
2、如果自己在後退棧中,就將自己從後退棧中移除掉(彈出)
3、如果自己不在後退棧中,就將自己從FragmentManager中移除掉。
關於commitAllowingStateLoss與commit的區別,網上有很多講解,這裡也不細說了。以後的FragmentManager中,會對它有更詳細的解釋。
今天就先寫到這裡,後面部分下次發布。
在Android的3.0之後,google又提出了屬性動畫的這樣一個框架,他可以更好的幫助我們實現更豐富的動畫效果。所以為了跟上技術的步伐,今天就聊一聊屬性動畫。這一次的
華為手機基於Android打造了EMUI系統,目前最新版本是EMUI 4.1,版本是Android 6.0。據荷蘭媒體報道,他們從產業鏈獲悉,華為正在秘研E
今天地鐵上看到一篇不錯的將內存洩漏簡單檢查的文章,覺得還不錯喲,內存洩漏確實是每個程序員頭疼的事情,這裡就多研究一下咯^^一. 常見的垃圾回收算法參看文章引用計數法引用計
我手機的關於手機界面:說明:其中手機型號、Android版本、軟件版本通過系統Build類得到,處理器信息、內核版本通過讀取系統文件得到,基帶版本信息通過反射得到。&nb