對(duì)話框 DialogFragment

對(duì)話框是提示用戶作出決定輸入額外信息的小窗口。
對(duì)話框不會(huì)填充屏幕,通常用于需要用戶采取行動(dòng)才能繼續(xù)執(zhí)行的模式事件。

通常將 DialogFragment 用作對(duì)話框的容器,通過(guò)fragment實(shí)現(xiàn)dialog的好處是:
activity配置改變(例如轉(zhuǎn)向)進(jìn)行重構(gòu)的情況下,fragment管理器能夠自動(dòng)重構(gòu),恢復(fù)原來(lái)的狀態(tài),無(wú)需人工干預(yù),并且能夠它能正確處理生命周期事件

創(chuàng)建


通過(guò)newInstance()創(chuàng)建實(shí)例,并返回

  1. 通過(guò)缺省構(gòu)造函數(shù)創(chuàng)建對(duì)象
  2. 將傳遞的信息設(shè)置為fragment的參數(shù)
  3. 返回對(duì)象
public class MyDialogFragment extends DialogFragment {

    public static MyDialogFragment newInstance(int num) {
        MyDialogFragment f = new MyDialogFragment();

        Bundle args = new Bundle();
        args.putInt("num", num);
        f.setArguments(args);

        return f;
    }

onCreate回調(diào)中可以設(shè)置對(duì)話框的style、theme等屬性,恢復(fù)保存的數(shù)據(jù)等

setCancelable(boolean cancelable)

控制對(duì)話框是否可以取消
參數(shù)為true,點(diǎn)擊dialog覆蓋不到的activity的空白或按返回鍵,就取消,依次執(zhí)行onCancel()和onDismiss()回調(diào)
如參數(shù)為false,則按空白處或返回鍵無(wú)反應(yīng)
默認(rèn)為true,可以取消

setStyle(int style, int theme)

設(shè)置dialog的顯示風(fēng)格
例如style為STYLE_NO_TITLE,將不顯示title
theme為0,表示由系統(tǒng)選擇合適的theme。
風(fēng)格也可以在資源文件的styles.xml文件中自己設(shè)定,然后配置進(jìn)來(lái)

    @Override 
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        if(savedInstanceState != null){
        ...
        }

        setCancelable(false); 
       
        int style = DialogFragment.STYLE_NO_TITLE;
        int theme =android.R.style.Theme_Holo_Light_Dialog; 
        setStyle(style,theme);  
    }  
...
}

通過(guò)onCreateView()設(shè)置UI和按鍵反饋


自定義對(duì)話框時(shí)通常重載Fragment的onCreateView(LayoutInflater, ViewGroup, Bundle),返回一個(gè)View,實(shí)現(xiàn)dialog的UI

  1. 通過(guò)inflate,根據(jù)layout XML定義,創(chuàng)建view
  1. 對(duì)view中的組件進(jìn)行綁定、設(shè)置 (findViewById
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        
        View v = inflater.inflate(R.layout.prompt_dialog, container,false); 
        TextView tv = (TextView)v.findViewById(R.id.prompt_message); 
        tv.setText(getPrompt()); 
      
        Button dismissBtn = (Button)v.findViewById(R.id.button_dismiss); 
        dismissBtn.setOnClickListener(this);          
        Button saveBtn = (Button)v.findViewById(R.id.button_save); 
        saveBtn.setOnClickListener(this);          

        return v; 
    } 

通過(guò)onCreateDialog()創(chuàng)建對(duì)話框UI

對(duì)于簡(jiǎn)單的對(duì)話框,可以通過(guò)AlterDialog.Builder直接創(chuàng)建對(duì)話框的UI,例如警告提醒,最后返回一個(gè)Dialog

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState) {
        AlertDialog.Builder b = new AlertDialog.Builder(getActivity()) 
                                    .setTitle(R.string.select) 
                                    .setView(initView())  //setMessage(getMessage()) 
                                    .setPositiveButton(android.R.string.ok, this)  //設(shè)置回調(diào)函數(shù) 
                                    .setNegativeButton(android.R.string.cancel,this); //設(shè)置回調(diào)函數(shù)
                                    .setNeutralButton(R.string.refresh, null);//中性按鈕
 
        builder.setPositiveButton(android.R.string.ok, mDialogClickListener);
        builder.setNegativeButton(android.R.string.cancel, mDialogClickListener);
        builder.setNeutralButton(R.string.refresh, null);

        final Dialog dialog = builder.create();

        dialog.setCancelable(true);
        dialog.setCanceledOnTouchOutside(true);

        return dialog;
    }

set...Button()方法需要一個(gè)按鈕標(biāo)題(由字符串資源提供)和一個(gè) DialogInterface.OnClickListener接口實(shí)現(xiàn),用于定義用戶按下該按鈕時(shí)執(zhí)行的操作。

調(diào)用 setView()將自定義布局放入對(duì)話框

final View rootView = getActivity().getLayoutInflater().inflate(R.layout.XXXXX, null);

顯示和關(guān)閉對(duì)話框


顯示有兩個(gè)函數(shù),兩個(gè)方法內(nèi)部都調(diào)用了 add()和commit()函數(shù)

  1. public void show(FragmentManager manager, String tag)
  2. public int show(FragmentTransaction transaction, String tag)
    對(duì)于將fragment transaction作為參數(shù)的方式,在調(diào)用show()之前,可通過(guò)fragment transaction進(jìn)行控制,如加入到back stack中
void showDialog() {

    //清除已經(jīng)存在的,同樣的fragment
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance();
    newFragment.show(ft, "dialog");
}

關(guān)閉
dismiss() 內(nèi)部執(zhí)行 FragmentTransaction的 remove()和commit() 并觸發(fā)onDismiss()回調(diào)函數(shù)。如果back stack堆棧有該dialog,會(huì)將其彈出來(lái)

將事件傳遞回對(duì)話框的宿主


public class NoticeDialogFragment extends DialogFragment {

    /* 創(chuàng)建對(duì)話框片段的Activity實(shí)現(xiàn)此接口,用來(lái)接收回調(diào)事件
     * 每個(gè)方法傳遞DialogFragment,用來(lái)查詢信息 */
    public interface NoticeDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }

    // 接口實(shí)例來(lái)傳遞動(dòng)作事件
    NoticeDialogListener mListener;

    // 方法來(lái)實(shí)例化NoticeDialogListener
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // Verify that the host activity implements the callback interface
        try {
            // Instantiate the NoticeDialogListener so we can send events to the host
            mListener = (NoticeDialogListener) activity;
        } catch (ClassCastException e) {
            // The activity doesn't implement the interface, throw exception
            throw new ClassCastException(activity.toString()
                    + " must implement NoticeDialogListener");
        }
    }
    ...
}

Reference


Android Developers:對(duì)話框
DialogFragment
DialogFragment詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容