Android:我為何要封裝DialogFragment?
來自: http://www.jianshu.com/p/af6499abd5c2
我為何要封裝DialogFragment
最近在重構項目代碼,項目中創建對話框用的是Dialog,AlertDialog。但是官方推出了DialogFragment來代替Dialog。那我就去認真的了解下DialogFragment。
DialogFragment
DialogFragment是在Android3.0的時候被引入的,從其名字可以很直觀的看出它是一種基于Fragment的Dialog,可以用來創建對話框,它是用來替代Dialog的。一個新事物的出現是為了解決舊事物存在的問題,那不建議使用的Dialog存在什么問題呢?下面簡單的說下。
Dialog存在問題:
- 在手機配置發生變化后(比如:旋屏后),變化之前顯示的Dialog,變化之后不會顯示,更別提Dialog狀態的恢復了。
- 管理自定義的Dialog和系統原生的Dialog麻煩
DialogFragment怎么解決Dialog存在的問題:
- DialogFragment說到底還是一個Fragment,因此它繼承了Fragment的所有特性。同理FragmentManager會管理DialogFragment。在手機配置發生變化的時候,FragmentManager可以負責現場的恢復工作。調用DialogFragment的setArguments(bundle)方法進行數據的設置,可以保證DialogFragment的數據也能恢復。
- DialogFragment里的onCreateView和onCreateDIalog 2個方法,onCreateView可以用來創建自定義Dialog,onCreateDIalog 可以用Dialog來創建系統原生Dialog。可以在一個類中管理2種不同的dialog。
用DialogFragment替代Dialog
既然DialogFragment有這些好處,那我就毅然決然的對項目中的Dialog用DialogFragment來進行替代。
重構的思路是這樣的:
- 首先先創建一個ConfirmDialogFragment類(該類是用來創建確認對話框的),ConfirmDialogFragment類繼承了DialogFragment。
- 其次在創建一個ProgressDialogFragment類(該類是用來創建進度對話框),同時它也繼承了DialogFragment。
- 其他類型的Dialog就不舉例了。
- 最后在BaseActivity(項目中所有Activity的基類)添加顯示Dialog的方法,供BaseActivity的子類、Fragment、還有非Activity和非Fragment的類來調用。
我們先看下關鍵代碼片段:代碼地址
ConfirmDialogFragment中的代碼片段:代碼地址
/**
*用來創建確認對話框
* Created by niuxiaowei on 2015/10/16.
*/
public class ConfirmDialogFragment extends DialogFragment{
private ConfirmDialogListener mListener;
//對外開放的接口
public static interface ConfirmDialogListener extends DialogInterface.OnClickListener{
}
/**
* @param title
* @param message
* @param cancelable
* @return
*/
public static ConfirmDialogFragment newInstance(String title, String message,boolean cancelable){
ConfirmDialogFragment instance = new ConfirmDialogFragment();
Bundle args = new Bundle();
args.putString("title",title);
args.putString("message",message);
args.putBoolean("cancelable",cancelable);
instance.setArguments(args);
return instance;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
創建ConfirmDialog核心代碼,可以下載源代碼查看.....
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (getActivity() instanceof ConfirmDialogListener ) {
mListener= (ConfirmDialogListener ) getActivity();
}
}
......
} ConfirmDialogFragment很關鍵的一點,ConfirmDialogFragment中的mListener屬性的值是通過
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (getActivity() instanceof ConfirmDialogListener ) {
mListener= (ConfirmDialogListener ) getActivity();
}
} 方式獲取的。
BaseActivity中代碼片段:代碼地址
public class BaseActivity extends FragmentActivity
{
/*
*顯示確認對話框方法
*/
public void showConfirmDialog(...){
......
}
/*
*顯示進度條對話框方法
*/
public void showProgressDialog(...){
......
}
} 那我們就重構BaseActivity的子類顯示Dialog的代碼:
我拿MainActivity來舉例子:
MainActivity的關鍵重構代碼:
/*
*實現確認對話框的ConfirmDialogListener 接口
*created by niuxiaowei
*/
public class MainActivity extends BaseActivity implements ConfirmDialogListener {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(this,"點擊了MainActivity 調起的確認對話框 i="+i,Toast.LENGTH_LONG).show();
}
//調用顯示ConfirmDialog代碼
showConfirmDialog(...);
//調用顯示ProgressDialog代碼
showProgressDialog(...);
} 現在MainActivity里的代碼運行起來完全沒問題,因為MainActivity里面包含了3個Fragment,每個Fragment里面都有顯示ConfirmDialog和ProgressDialog的代碼,所以開始重構這3個Fragment:
重構思路:
- 每個Fragment里都可以獲取到相對應的Activity的實例,只要獲取到實例就可以調用顯示對話框的方法來顯示對話框了。
- 對話框中的事件怎么傳遞給Fragment問題?Activity可以獲取到Fragment的實例,對話框可以把事件傳遞給Activity,因此Activity順理成章的可以把事件傳遞給對應的Fragment。
-
一個Activity有多個Fragment調用顯示對話框的方法,在Activity的實現了對話框接口的方法里怎樣區分不同的Fragment調用者?可以在BaseActivity顯示對話框的方法里加個id參數,用id來區分不同的Fragment調用者。
那就上關鍵代碼片段:
MainActivity中的AFragment代碼片段:public AFragment extends Fragment implements ConfirmDialogListener{ @Override public void onClick(DialogInterface dialogInterface, int i) { Toast.makeText(this,"點擊了AFragment 調起的確認對話框 i="+i,Toast.LENGTH_LONG).show(); } //調用顯示ConfirmDialog代碼 getActivity().showConfirmDialog(...); }
同理MainActivity的BFragment,CFragment的重構與AFragment類似。
MainActivity的關鍵代碼片段:
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//偽代碼
if(mId == aFragment傳遞Id){
aFragment.onClick(dialogInterface,i);
}else if(mId == bFragment傳遞Id){
}else if(mId == cFragment傳遞Id){
}else if(mId == mainActiviy傳遞Id){
調用自己的方法
}
} 產生的問題
看了MainActivity的onClick方法里面代碼我都對自己無語了,onClick方法里面充斥著各種的if else 語句,并且當前的MainActivity里,若再有別的顯示ConfirmDialog的調用者,onClick方法里少不了要增加對應的else if語句。MainActivity只是項目中所有Activity的一個縮影。其他的Activity也會遇到同樣的問題(這不是我意淫的,提早預估到問題,提早入手進行解決總是好的)
我們拿MainActivity來代表所有的Activity總結下使用DialogFragment創建Dialog產生的問題:
- MainActivity里的onClick方法維護、擴展性不好,充斥著各種if else if語句,可讀性也不好。
- MainActivity里的onClick方法除了把Dialog的事件轉發給相對應的調用者之外,沒有多任何其他操作,所以是多余的
- 顯示Dialog的方法不靈活
存在這些問題嚴重影響了我后面的重構工作,于是乎我就去國內國外網站上搜索對應的解決方法,但是也沒有找到好的方法,最后我就想辦法自己解決上面的問題,這也是我為何要封裝DialogFragment的緣由。
封裝DialogFragment,讓DialogFragment使用非常簡單、靈活
我們仔細的分析下上文的問題的主要原因是顯示Dialog的方法沒有把Dialog里面的開放的接口作為參數導致的,假如能像下面的使用方式:
//某一個Activity中顯示ConfirmDialog
showConfirmDialog(title,message,confirmDialogListener);
//某一個Fragment中顯示ConfirmDialog
getActivity().showConfirmDialog(this,message,confirmDialogListener);
//非Activity和非Fragment的類中顯示ConfirmDialog
mActivity.showConfirmDialog(this,message,confirmDialogListener); 上文中所有的問題都可以解決。
為什么不按下面的做法做
做法1:那我們直接把ConfirmDialogListener 的實例賦值給ConfirmDialogFragment 的實例的mListener屬性,以下為代碼:
//直接把listener傳遞
public static ConfirmDialogFragment newInstance(...,ConfirmDialogListener listener){
ConfirmDialogFragment instance = new ConfirmDialogFragment();
......
instance.mListener = listener;
......
} 那我就詳細的解釋下為什么不這樣做的具體原因:
- 在創建Fragment的時候,最好是把傳遞給Fragment的數據存放在Bundle中,然后在調用fragment的setArguments(bundle)方法進行數據的設置,這種做法好處是:系統會保存Fragment的數據,在手機配置發生變化后(比如旋屏),系統會把保存的Fragment數據進行恢復。
以上做法,ConfirmDialogFragment 中mListener屬性系統沒有為之保存,所以手機配置發生變化后,ConfirmDialogFragment 中的mListener 是null。
做法2:那我們是否可以把ConfirmDialogListener實例(ConfirmDialogListener是ConfirmDialogFragment 對外開放的接口)存放在Bundle中?
答案是不可以,首先 Bundle對存放的數據是有限制的,把ConfirmDialogListener的實例存入Bundle中是比較復雜的操作。其次即使通過艱辛萬苦把ConfirmDialogListener實例存入了Bundle中,保存ConfirmDialogListener實例是毫無意義的,只有保存數據對于Fragment來說才有意義,保存行為對Fragment是無意義的。
有思路
我們在回顧下ConfirmDialogFragment中onAttach的方法的關鍵代碼:代碼地址
@Override
public void onAttach(Activity activity) {
if(getActivity() instanceof ConfirmDialogListener){
//關鍵代碼
mListener= (ConfirmDialogListener)getActivity();
}
} 以上代碼的關鍵之處在于mListener= (ConfirmDialogListener)getActivity()。同時痛點也在此處,這是一種類似于硬編碼的方式,硬編碼的一個不好的地方就是沒有擴展性。解決思路:
- 那我們就想辦法讓此處變的有彈性。我們可以把BaseActivity想象為一個ConfirmDialogListener的存取工具,調用者可以把自己實現的ConfirmDialogListener存入BaseActivity中, ConfirmDialogFragment可以從BaseActivity中取出ConfirmDialogListener實例,那我的問題就迎刃而解了。
- 既然可以獲取到BaseActivity的實例,那也可以獲取到BaseFragment的實例(getParentFragment()可以獲取到)。既然BaseFragment實例可以獲取到,那解決ConfirmDialogFragment同時服務于BaseActivity和BaseFragment就不是問題了。
同時我還想解決在任何的類中(不管Fragment、Activity、或其他類中)顯示Dialog不需要依賴BaseActivity。而是有一個類(假如叫DialogFactory)定義顯示各種Dialog的方法。像下面一樣:
//某一個Activity中顯示ConfirmDialog
mDialogFactory.showConfirmDialog(title,message,confirmDialogListener);
//某一個Fragment中顯示ConfirmDialog
mDialogFactory.showConfirmDialog(this,message,confirmDialogListener);
//非Activity和非Fragment的類中顯示ConfirmDialog
mDialogFactory.showConfirmDialog(this,message,confirmDialogListener); 那我就說下思路:
- 新建DialogFactory類,該類封裝了顯示各種Dialog的方法
- 新建BaseDialogFragment類,該類是各種類型Dialog的基類,里面封裝了一些公用的方法
- 修改BaseActivity和BaseFragment類,在各自的類中分別定義DialogFactory屬性mDialogFactory,這樣顯示Dialog的任務就交給了mDialogFactory
DialogFactory 代碼:代碼地址
/** * Created by niuxiaowei on 2016/2/3. * 對話框工廠 */
public class DialogFactory {
private FragmentManager mFragmentManager;
private BaseActivity mBaseActivity;
private BaseFragment mBaseFragment;
public DialogFactory(BaseActivity baseActivity,FragmentManager fragmentManager){
this.mFragmentManager = fragmentManager;
this.mBaseActivity = baseActivity;
}
public DialogFactory(BaseFragment baseFragment,FragmentManager fragmentManager){
this.mFragmentManager = fragmentManager;
this.mBaseFragment= baseFragment;
}
/** * 進度條對話框
* @param message 進度條顯示的信息
* @param cancelable 點擊空白處是否可以取消 */
public void showProgressDialog(String message, boolean cancelable){
省略此處代碼......
}
/**
* 顯示確認對話框,dialogId是用來區分不同對話框的
* @param title 對話框title
* @param message
* @param cancelable
* @param listener
*/
public void showConfirmDialog(String title,String message,boolean cancelable,ConfirmDialogListener listener){
省略此處代碼......
if(mBaseActivity != null){
mBaseActivity.setDialogListener(listener);
}else if(mBaseFragment != null){
mBaseFragment.setDialogListener(listener);
}
}
顯示其他類型的dialog方法......
} DialogFactory關鍵代碼介紹:
- DialogFactory可以供任何的類來使用
- mFragmentManager屬性在現實Dialog時起作用,若調用者(顯示Dialog)是Activity,則傳遞getFragmentManager();若調用者是Fragment,則傳遞getChildFragmentManager()。不過不需要擔心這些,BaseActivity和BaseFragment都已經封裝了這些參數
- DialogFactory把調用者傳遞過來的BaseDialogListener傳遞給Activity或Fragment
BaseDialogFragment代碼:代碼地址
/** * Created by niuxiaowei on 2015/10/15. * 自定義dialog,是所有自定義dialog的基類 */
public class BaseDialogFragment extends DialogFragment {
/** * 基礎的dialog listener,沒有提供任何的方法,擴展的dialog,若該dialog有listener則必須繼承本接口 */
public static interface BaseDialogListener{}
/** * 接收dialog listener對象,具體由子類進行實現 * @param listener */
protected void onReceiveDialogListener(BaseDialogListener listener){}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
/*解析BaseDialogListener,fragment的級別要大于activity,若
* (getParentFragment() instanceof BaseFragment)為true* ,
* 表明是一個fragment調起的dialog,否則是一個activity調起的diaolog
* */
BaseDialogListener listener = null;
if (getParentFragment() instanceof BaseFragment) {
listener = ((BaseFragment) getParentFragment()).getDialogListener();
}else if(getActivity() instanceof BaseActivity){
listener = ((BaseActivity)getActivity()).getDialogListener();
}
if(listener != null){
onReceiveDialogListener(listener);
}
}
} BaseDialogFragment關鍵代碼介紹:
- BaseDialogListener定義一個空方法接口,新增的Dialog(若該Dialog包含對外接口),則新增的Dialog提供的對外接口必須繼承BaseDialogListener
- onReceiveDialogListener方法是提供給子類來實現,讓子類來接收調用者傳遞進來的BaseDialogListener實例
-
onActivityCreated方法很重要,該方法是使BaseDialogFragment可以兼容Activity和Fragment的關鍵代碼
if (getParentFragment() instanceof BaseFragment) { listener = ((BaseFragment) getParentFragment()).getDialogListener(); }else if(getActivity() instanceof BaseActivity){ listener = ((BaseActivity)getActivity()).getDialogListener(); }上面代碼的作用是假如當前調用者(顯示Dialog)是一個Fragment,則會把Fragment中持有的BaseDialogListener賦給對應的Dialog,若當前調用者是一個Activity,則會做同樣的事情
ConfirmDialogFragment 關鍵代碼片段:代碼地址
//繼承BaseDialogListener
public static interface ConfirmDialogListener extends BaseDialogListener,DialogInterface.OnClickListener{
}
public void onReceiveDialogListener(BaseDialogListener listener){
if(listener instanceof ConfirmDialogListener ){
mListener = (ConfirmDialogListener )listener;
}
} ProgressDialogFragment基本沒發生多大改變,我們就不貼具體代碼了。
修改BaseActivity和BaseFragment類關鍵代碼:
public class BaseActivity extends FragmentActivity{
protected DialogFactory mDialogFactory ;
private BaseDialogListener mListener;
public void getDialogListener(){
return mListener;
}
public void setDialogListener(BaseDialogListener listener){
mListener = listener;
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mDialogFactory = new DialogFactory(this,getFragmentManager();
}
}
public class BaseFragment extends Fragment{
protected DialogFactory mDialogFactory ;
private BaseDialogListener mListener;
public void getDialogListener(){
return mListener;
}
public void setDialogListener(BaseDialogListener listener){
mListener = listener;
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mDialogFactory = new DialogFactory(this,getChildFragmentManager();
}
} 介紹下BaseActivity修改的代碼:
- mDialogFactory 是供Activity來顯示各種Dialog的
- mListener是Activity持有調用者傳遞的BaseDialogListener的實例,BaseDialogFragment會從getDialogListener()方法獲取該實例
BaseFragment的修改和BaseActivity一樣,就不介紹了。
那我們在理一下上面代碼的思路:
- DialogFactory封裝了顯示各種Dialog的方法,使用者使用它來顯示Dialog。它會把使用者傳遞的BaseDialogListener傳遞給BaseActivity或BaseFragment
- BaseActivity和BaseFragment在傳遞BaseDialogListener起了一個橋梁的作用。當Dialog即將被顯示時,BaseDialogFragment會從BaseActivity或BaseFragment獲取BaseDialogListener
解決最棘手的問題
當我還沉浸在happy中時,突然一個問題出現了,旋屏后重新彈出的ConfirmDialog的點擊事件卻沒傳遞給調用者,我就細細的想原來是旋屏后BaseActivity或BaseFragment里的mListener為空了。那我就繼續解決這棘手問題,為什么棘手呢?因為我們一直都是在圍繞著怎樣解決旋屏后Dialog中的mListener屬性的值(BaseDialogListener的實例)怎么重新獲取的問題,但是經過一番努力還是沒成功,不行我還得繼續想辦法。
上文中也提到過對于Fragment存放行為是毫無意義的,那我們就換個角度考慮問題,我們先用BaseFragment來舉例子(BaseActivity類似):
- 在BaseFragment用一個屬性mDialogListenerKey去存mListener(類型是BaseDialogListener)屬性的類名,當手機配置發生變化的時候在BaseFragment的onSaveInstance(bundle)方法中把mDialogListenerKey存入Bundle中(前提條件Dialog沒消失)
- 當BaseFragment重新被創建的時候,在onCreate(savedInstanceState)方法中從Bundle中把mDialogListenerKey值讀出來
- 根據mDialogListenerKey去找到對應的BaseDialogListener子類的實例
- 把上步中找到的實例通過調用BaseFragment的setDialogListener()方法進行設置
那我們就開始寫代碼:
新建DialogListenerHolder,該類用來持有調用者傳遞的BaseDialogListener實例,即把原來BaseActivity或BaseFragment里的mListener屬性放到該類中
DialogListenerHolder修改的代碼片段:代碼地址
public class DialogListenerHolder{
private BaseDialogListener mDialogListener;
/** * 對話框的listener的key值,用類名作為key值,
*主要用來在手機配置發生變化時(橫屏換為豎屏),
*當現場恢復時,能正確的找到對話框的listener */
private String mDialogListenerKey;
public void setDialogListener(BaseDialogFragment.BaseDialogListener listener){
mDialogListener = listener;
mDialogListenerKey = listener == null ?null:listener.getClass().getName();
}
/** * 把listener的key值保存在bundle中,配置發生變化的情況下(橫屏換為豎屏),在從bundle中取listener的key值
* @param outState */
public void saveDialogListenerKey(Bundle outState){
if(outState != null){
outState.putString("key",mDialogListenerKey);
}
}
/** * 從bundle中嘗試取出dialog listener key
* @param savedInstanceState */
public void getDialogListenerKey(Bundle savedInstanceState){
if(savedInstanceState != null){
mDialogListenerKey = savedInstanceState.getString("key");
}
}
/** * 這個方法很重要,是恢復dialog listener的一個關鍵點,
*在初始化DialogFactory或把DialogFactory賦值后,調用該方法,把調用該方法所在
* 的類的實例作為參數。 該方法會把param中的屬性依次遍歷,嘗試找屬性是BaseDialogFragment.BaseDialogListener的實例,
* 并且該屬性就是保存在bundle中的dialog listener key對應的dialog listener
* @param o */
public void restoreDialogListener(Object o){
if(o == null){
return;
}
if(!isNeedRestoreDialogListener()){
return;
}
//先嘗試找傳進來的實例
if(o instanceof BaseDialogFragment.BaseDialogListener && o.getClass().getName().equals(mDialogListenerKey))
{
setDialogListener((BaseDialogFragment.BaseDialogListener)o);
return;
}
Class c = o.getClass();
Field[] fs = c.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
Field f = fs[i];
try {
Object instance = f.get(o);
if((instance instanceof BaseDialogFragment.BaseDialogListener) && instance.getClass().getName().equals(mDialogListenerKey)){
setDialogListener((BaseDialogFragment.BaseDialogListener) f.get(o));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
private boolean isNeedRestoreDialogListener(){
return mDialogListenerKey == null? false:mDialogListener== null;
}
} 代碼有點復雜我先簡單介紹下:
DialogListenerHolder中的mDialogListenerKey是存BaseDialogListener的子類的類名。
DialogListenerHolder中的saveDialogListenerKey(Bundle outState)方法是把mDialogListenerKey存到Bundle中,這樣系統就可以存儲下該值。供BaseActivity或BaseFragment的onSaveInstanceState(Bundle outState)方法調用。
DialogListenerHolder中的getDialogListenerKey(Bundle savedInstanceState)方法是從Bundle中取出mDialogListenerKey,供BaseActivity或BaseFragment的onCreate(Bundle savedInstanceState)調用。
DialogListenerHolder中的restoreDialogListener(Object o)方法很重要,作用是從參數o中去查找mDialogListenerKey對應的BaseDialogListener(查找范圍是參數o和o中的屬性),若找到并調用setDialogListener()方法。
所以這里對于調用者(調起Dialog)傳遞的BaseDialogListener有個要求:調用者實現了BaseDialogListener的子類或者調用者包含BaseDialogListener的子類的一個public屬性
DialogFactory修改代碼片段:代碼地址
private DialogListenerHolder mListenerHolder;
public DialogFactory(FragmentManager fragmentManager, Bundle savedInstanceState){
this.mFragmentManager = fragmentManager;
mListenerHolder.getDialogListenerKey(savedInstanceState);
}
public void restoreDialogListener(Object o){
mListenerHolder.restoreDialogListener(o);
} BaseActivity修改代碼片段:代碼地址
public BaseDialogFragment.BaseDialogListener getDialogListener() {
return mDialogFactory.mListenerHolder.getDialogListener();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mDialogFactory.mListenerHolder.saveDialogListenerKey(outState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDialogFactory = new DialogFactory(getSupportFragmentManager(),savedInstanceState);
mDialogFactory.restoreDialogListener(this);
} BaseFragment修改代碼片段:代碼地址
public BaseDialogFragment.BaseDialogListener getDialogListener() {
return mDialogFactory.mListenerHolder.getDialogListener();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mDialogFactory.mListenerHolder.saveDialogListenerKey(outState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mDialogFactory = new DialogFactory(getChildFragmentManager(),savedInstanceState);
mDialogFactory.restoreDialogListener(this);
} 到此為止我們的封裝就一切ok了,高興下。
總結
經過一步步艱辛的路程,封裝DialogFragment的工作終于結束了,封裝好的Dialog架構可以給您帶來以下好處:
-
可以讓DialogFragment的使用像Dialog一樣的簡單、靈活,同時也保持了DialogFragment的優點,可以在任何的類中使用。就像下面代碼:
//某一個Activity中顯示ConfirmDialog mDialogFactory.showConfirmDialog(title,message,confirmDialogListener); //某一個Fragment中顯示ConfirmDialog mDialogFactory.showConfirmDialog(this,message,confirmDialogListener); //非Activity和非Fragment的類中顯示ConfirmDialog mDialogFactory.showConfirmDialog(this,message,confirmDialogListener);
- 很簡單的新增新類型的Dialog
同時在使用的時候需要注意以下幾點:
1 . 在既不是Activity也不是Fragment的類(下面我們簡稱該類)中調起Dialog要求:
- 該類擁有DialogFactory 屬性(DialogFactory 的值是從繼承了BaseActivity的Activity或繼承了BaseFragment的Fragment傳遞進來的)
- 在給DialogFactory 屬性賦值后,緊接著需要調用DialogFactory 的restoreDialogListener(Object)方法
- 該類實現了XXDialogListener或者該類包含XXDialogListener這樣的一個屬性(該屬性權限必須是public)
2 .在繼承了BaseActivity的Activity(簡稱activity)中或者繼承了BaseFragment的Fragment(簡稱fragment)中調起Dialog的要求:
- activity或fragment實現了XXDialogListener或者是activity或fragment包含XXDialogListener這樣的一個public類型的屬性。
3 .若需要創建新的類型的Dialog,需要注意的是:
- 繼承BaseDialogFragment
- 若該Dialog對外提供接口(接口需要繼承BaseDialogListener,需要實現onReceiveDialogListener()方法)
以上是我個人的總結,希望對給Android學習者提供幫助。代碼地址