Android中DialogFragment如何使用,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
基本用法
對于方法 ①,創建一個 Dialog 并返回它即可:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//為了樣式統一和兼容性,可以使用 V7 包下的 AlertDialog.Builder
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// 設置主題的構造方法
// AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);
builder.setTitle("注意:")
.setMessage("是否退出應用?")
.setPositiveButton("確定", null)
.setNegativeButton("取消", null)
.setCancelable(false);
//builder.show(); // 不能在這里使用 show() 方法
return builder.create();
}當然,你也可以使用自定義 View 來創建:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// 設置主題的構造方法
// AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.fragment_dialog, null);
builder.setView(view)
// Do Someting,eg: TextView tv = view.findViewById(R.id.tv);
return builder.create();
}PS:創建 Dialog 的方式有多種,比如下面這種,使用時略有差異,需要自己注意:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.fragment_dialog, null);
Dialog dialog = new Dialog(getActivity());
// 設置主題的構造方法
// Dialog dialog = new Dialog(getActivity(), R.style.CustomDialog);
dialog.setContentView(view);
// Do Someting
return dialog;
}對于方法 ②,和普通的 Fragment 用法基本一致:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_dialog, container, false);
// Do Someting
return rootView;
}
/**
* 設置主題需要在 onCreate() 方法中調用 setStyle() 方法
*/
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.CustomDialog);
}處理屏幕翻轉
如果使用傳統的 Dialog ,需要我們手動處理屏幕翻轉的情況,但使用 DialogFragment 的話,則不需要我們進行任何處理,FragmentManager 會自動管理 DialogFragment 的生命周期。
無標題欄/全屏
在基本用法里代碼注釋有設置主題的地方,下面詳細說下兩種方法下設置無標題欄和實現全屏的方式:
無標題欄
對于方法 ① :
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.fragment_dialog, null);
Dialog dialog = new Dialog(getActivity(), R.style.CustomDialog);
// 關閉標題欄,setContentView() 之前調用
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
dialog.setCanceledOnTouchOutside(true);
return dialog;
}對于方法 ②:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* setStyle() 的第一個參數有四個可選值:
* STYLE_NORMAL|STYLE_NO_TITLE|STYLE_NO_FRAME|STYLE_NO_INPUT
* 其中 STYLE_NO_TITLE 和 STYLE_NO_FRAME 可以關閉標題欄
* 每一個參數的詳細用途可以直接看 Android 源碼的說明
*/
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.CustomDialog);
}實現全屏(寬/高度全屏)
常用的形式大多是寬度上和屏幕一樣寬,高度自適應,下面直接看代碼:
方法 ① :
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.fragment_dialog, null);
Dialog dialog = new Dialog(getActivity(), R.style.CustomDialog);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
dialog.setCanceledOnTouchOutside(true);
//Do something
// 設置寬度為屏寬、位置靠近屏幕底部
Window window = dialog.getWindow();
window.setBackgroundDrawableResource(R.color.transparent);
WindowManager.LayoutParams wlp = window.getAttributes();
wlp.gravity = Gravity.BOTTOM;
wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(wlp);
return dialog;
}代碼 12 行設置了窗口的背景色為透明,這一步是必須的;
代碼 15 行設置窗口的寬度為 MATCH_PARENT,效果是和屏幕寬度一樣大,同樣你也可以設置高度的值。設置寬度和高度除了 MATCH_PARENT 和 WRAP_CONTENT ,也可以直接設置成具體的數值。
方法 ②:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.CustomDialog);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().setCanceledOnTouchOutside(true);
View rootView = inflater.inflate(R.layout.fragment_dialog, container, false);
//Do something
// 設置寬度為屏寬、靠近屏幕底部。
final Window window = getDialog().getWindow();
window.setBackgroundDrawableResource(R.color.transparent);
window.getDecorView().setPadding(0, 0, 0, 0);
WindowManager.LayoutParams wlp = window.getAttributes();
wlp.gravity = Gravity.BOTTOM;
wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(wlp);
return rootView;
}代碼 14 行設置了窗口的背景色為透明,這一步是必須的;
代碼 15 行設置了窗口的 Pading 值全部為0,這一步也是必須的,內容不能填充全部寬度和高度。
其他的和 ① 中的類似。
應用場景區別
文章一開始簡單總結了方法 ① 和方法 ② 的應用場景,這里說明下:
1. 從基本的用法中可以看到方法 ① 為簡單的替代 Dialog 提供了非常方便的創建方式,比方法 ② 有優勢
2. 方法 ① 在使用了多線程(例如網絡請求)的情況下,不能正確的獲取當前 Fragment 的狀態,會產生空指針異常。方法 ② 則沒有此問題,而且,其創建方式默認使用了自定義 View,更便于應對復雜 UI 的場景。
這里舉例說明:方法 ① 和方法 ② 的//Do something 代碼處,我們進行一些異步操作:
TextView title = rootView.findViewById(R.id.dialoag_tv);
title.setText("Value A");
new SomeTask().execute(url);
private class SomeTask extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
// 一些網絡請求
// 成功時 return true;
// 異常時 return false;
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
// if (!isVisible()) return;
if (aBoolean) {
title.setText("Value B");
}
}
}看完上述內容,你們掌握Android中DialogFragment如何使用的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。