對(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í)例,并返回
- 通過(guò)缺省構(gòu)造函數(shù)創(chuàng)建對(duì)象
- 將傳遞的信息設(shè)置為fragment的參數(shù)
- 返回對(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
- 通過(guò)inflate,根據(jù)layout XML定義,創(chuàng)建view
- 對(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ù)
- public void show(FragmentManager manager, String tag)
- 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");
}
}
...
}