欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android開發(fā)之DialogFragment用法實(shí)例總結(jié)

 更新時(shí)間:2017年11月17日 09:07:35   作者:Cafeting  
這篇文章主要介紹了Android開發(fā)之DialogFragment用法,結(jié)合實(shí)例形式總結(jié)分析了Android使用DialogFragment代替Dialog功能的相關(guān)使用技巧與注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了Android開發(fā)之DialogFragment用法。分享給大家供大家參考,具體如下:

背景

Android 官方推薦使用 DialogFragment 來(lái)代替 Dialog ,可以讓它具有更高的可復(fù)用性(降低耦合)和更好的便利性(很好的處理屏幕翻轉(zhuǎn)的情況)。

而創(chuàng)建 DialogFragment 有兩種方式:

1. 覆寫其 onCreateDialog 方法 — ①
2. 覆寫其 onCreateView 方法 — ②

雖然這兩種方式都能實(shí)現(xiàn)相同的效果,但是它們各有自己適合的應(yīng)用場(chǎng)景:

1. 方法 ①,一般用于創(chuàng)建替代傳統(tǒng)的 Dialog 對(duì)話框的場(chǎng)景,UI 簡(jiǎn)單,功能單一。
2. 方法 ②,一般用于創(chuàng)建復(fù)雜內(nèi)容彈窗或全屏展示效果的場(chǎng)景,UI 復(fù)雜,功能復(fù)雜,一般有網(wǎng)絡(luò)請(qǐng)求等異步操作。

應(yīng)用

基本用法

對(duì)于方法 ①,創(chuàng)建一個(gè) Dialog 并返回它即可:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
 //為了樣式統(tǒng)一和兼容性,可以使用 V7 包下的 AlertDialog.Builder
 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
 // 設(shè)置主題的構(gòu)造方法
 // AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.CustomDialog);
 builder.setTitle("注意:")
   .setMessage("是否退出應(yīng)用?")
   .setPositiveButton("確定", null)
   .setNegativeButton("取消", null)
   .setCancelable(false);
   //builder.show(); // 不能在這里使用 show() 方法
 return builder.create();
}

當(dāng)然,你也可以使用自定義 View 來(lái)創(chuàng)建:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
 // 設(shè)置主題的構(gòu)造方法
 // 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:創(chuàng)建 Dialog 的方式有多種,比如下面這種,使用時(shí)略有差異,需要自己注意:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
 LayoutInflater inflater = getActivity().getLayoutInflater();
  View view = inflater.inflate(R.layout.fragment_dialog, null);
 Dialog dialog = new Dialog(getActivity());
  // 設(shè)置主題的構(gòu)造方法
  // Dialog dialog = new Dialog(getActivity(), R.style.CustomDialog);
  dialog.setContentView(view);
  // Do Someting
 return dialog;
}

對(duì)于方法 ②,和普通的 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;
}
/**
 * 設(shè)置主題需要在 onCreate() 方法中調(diào)用 setStyle() 方法
 */
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setStyle(DialogFragment.STYLE_NO_TITLE, R.style.CustomDialog);
}

處理屏幕翻轉(zhuǎn)

如果使用傳統(tǒng)的 Dialog ,需要我們手動(dòng)處理屏幕翻轉(zhuǎn)的情況,但使用 DialogFragment 的話,則不需要我們進(jìn)行任何處理,FragmentManager 會(huì)自動(dòng)管理 DialogFragment 的生命周期。

無(wú)標(biāo)題欄/全屏

在基本用法里代碼注釋有設(shè)置主題的地方,下面詳細(xì)說(shuō)下兩種方法下設(shè)置無(wú)標(biāo)題欄和實(shí)現(xiàn)全屏的方式:

無(wú)標(biāo)題欄

對(duì)于方法 ① :

@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);
  // 關(guān)閉標(biāo)題欄,setContentView() 之前調(diào)用
 dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
 dialog.setContentView(view);
 dialog.setCanceledOnTouchOutside(true);
 return dialog;
}

對(duì)于方法 ②:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 /**
 * setStyle() 的第一個(gè)參數(shù)有四個(gè)可選值:
 * STYLE_NORMAL|STYLE_NO_TITLE|STYLE_NO_FRAME|STYLE_NO_INPUT
 * 其中 STYLE_NO_TITLE 和 STYLE_NO_FRAME 可以關(guān)閉標(biāo)題欄
 * 每一個(gè)參數(shù)的詳細(xì)用途可以直接看 Android 源碼的說(shuō)明
 */
 setStyle(DialogFragment.STYLE_NO_TITLE, R.style.CustomDialog);
}

實(shí)現(xiàn)全屏(寬/高度全屏)

常用的形式大多是寬度上和屏幕一樣寬,高度自適應(yīng),下面直接看代碼:

方法 ① :

@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
  // 設(shè)置寬度為屏寬、位置靠近屏幕底部
 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 行設(shè)置了窗口的背景色為透明,這一步是必須的;

代碼 15 行設(shè)置窗口的寬度為 MATCH_PARENT,效果是和屏幕寬度一樣大,同樣你也可以設(shè)置高度的值。設(shè)置寬度和高度除了 MATCH_PARENTWRAP_CONTENT ,也可以直接設(shè)置成具體的數(shù)值。

方法 ②:

@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
    // 設(shè)置寬度為屏寬、靠近屏幕底部。
    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 行設(shè)置了窗口的背景色為透明,這一步是必須的;

代碼 15 行設(shè)置了窗口的 Pading 值全部為0,這一步也是必須的,內(nèi)容不能填充全部寬度和高度。

其他的和 ① 中的類似。

應(yīng)用場(chǎng)景區(qū)別

文章一開始簡(jiǎn)單總結(jié)了方法 ① 和方法 ② 的應(yīng)用場(chǎng)景,這里說(shuō)明下:

1. 從基本的用法中可以看到方法 ① 為簡(jiǎn)單的替代 Dialog 提供了非常方便的創(chuàng)建方式,比方法 ② 有優(yōu)勢(shì)
2. 方法 ① 在使用了多線程(例如網(wǎng)絡(luò)請(qǐng)求)的情況下,不能正確的獲取當(dāng)前 Fragment 的狀態(tài),會(huì)產(chǎn)生空指針異常。方法 ② 則沒有此問(wèn)題,而且,其創(chuàng)建方式默認(rèn)使用了自定義 View,更便于應(yīng)對(duì)復(fù)雜 UI 的場(chǎng)景。

這里舉例說(shuō)明:方法 ① 和方法 ② 的//Do something 代碼處,我們進(jìn)行一些異步操作:

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) {
      // 一些網(wǎng)絡(luò)請(qǐng)求
      // 成功時(shí) return true;
      // 異常時(shí) return false;
    }
    @Override
    protected void onPostExecute(Boolean aBoolean) {
      super.onPostExecute(aBoolean);
      // if (!isVisible()) return;
      if (aBoolean) {
        title.setText("Value B");
      }
    }
}

如果在網(wǎng)絡(luò)請(qǐng)求未結(jié)束或者剛結(jié)束時(shí)關(guān)閉了當(dāng)前 DialogFragment ,代碼 19 行就會(huì)報(bào)空指針異常了,代碼 17 的作用就是判斷 DialogFragment 當(dāng)前的狀態(tài)是否為可用態(tài),但是 isVisible() 以及 isHide() 對(duì)于方法 ① 無(wú)法正確返回其狀態(tài),方法 ② 則正常。方法 ① 和方法 ② 創(chuàng)建 DialogFragment 的一些狀態(tài)并不是完全一致。

PS:你也可以使用靜態(tài) Handler 結(jié)合弱引用等來(lái)處理異步操作,那樣對(duì) DialogFragment 狀態(tài)的獲取就不重要了。

總結(jié)

以上是個(gè)人在實(shí)際開發(fā)過(guò)程中的一點(diǎn)總結(jié)和看法,希望你能抱著存疑的態(tài)度進(jìn)行嘗試,如果有新的觀點(diǎn)或者文章中有不正確的地方,歡迎和我聯(lián)系。

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問(wèn)題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)

希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Android開發(fā)實(shí)現(xiàn)模仿微信小窗口功能【Dialog對(duì)話框風(fēng)格窗口】

    Android開發(fā)實(shí)現(xiàn)模仿微信小窗口功能【Dialog對(duì)話框風(fēng)格窗口】

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)模仿微信小窗口功能,結(jié)合實(shí)例形式分析了Android實(shí)現(xiàn)微信風(fēng)格Dialog對(duì)話框窗口相關(guān)功能與布局操作技巧,需要的朋友可以參考下
    2019-03-03
  • Kotlin Service服務(wù)組件開發(fā)詳解

    Kotlin Service服務(wù)組件開發(fā)詳解

    這幾天分析了一下的啟動(dòng)過(guò)程,于是乎,今天寫一下Service使用; 給我的感覺是它并不復(fù)雜,千萬(wàn)不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個(gè)接著一個(gè),就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口
    2022-12-12
  • Android?studio實(shí)現(xiàn)單選按鈕

    Android?studio實(shí)現(xiàn)單選按鈕

    這篇文章主要為大家詳細(xì)介紹了Android?studio實(shí)現(xiàn)單選按鈕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Android 異步任務(wù) 設(shè)置 超時(shí)使用handler更新通知功能

    Android 異步任務(wù) 設(shè)置 超時(shí)使用handler更新通知功能

    這篇文章主要介紹了Android 異步任務(wù) 設(shè)置 超時(shí)使用handler更新通知,文中給大家提到了使用AsyncTask設(shè)置請(qǐng)求超時(shí)的注意事項(xiàng) ,需要的朋友可以參考下
    2017-12-12
  • Android Studio項(xiàng)目適配AndroidX(Android 9.0)的方法步驟

    Android Studio項(xiàng)目適配AndroidX(Android 9.0)的方法步驟

    這篇文章主要介紹了Android Studio項(xiàng)目適配AndroidX(Android 9.0)的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Android MVP模式實(shí)戰(zhàn)教程

    Android MVP模式實(shí)戰(zhàn)教程

    這篇文章主要為大家詳細(xì)介紹了Android MVP模式實(shí)戰(zhàn)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • android實(shí)現(xiàn)播放網(wǎng)絡(luò)視頻

    android實(shí)現(xiàn)播放網(wǎng)絡(luò)視頻

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)播放網(wǎng)絡(luò)視頻,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 使用Android開發(fā)接入第三方原生SDK實(shí)現(xiàn)微信登錄

    使用Android開發(fā)接入第三方原生SDK實(shí)現(xiàn)微信登錄

    這篇文章主要介紹了使用Android開發(fā)接入第三方原生SDK實(shí)現(xiàn)微信登錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • Android應(yīng)用框架之應(yīng)用啟動(dòng)過(guò)程詳解

    Android應(yīng)用框架之應(yīng)用啟動(dòng)過(guò)程詳解

    這篇文章主要為大家詳細(xì)介紹了Android應(yīng)用框架,應(yīng)用啟動(dòng)過(guò)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Kotlin語(yǔ)言中CompileSdkVersion與targetSdkVersion的區(qū)別淺析

    Kotlin語(yǔ)言中CompileSdkVersion與targetSdkVersion的區(qū)別淺析

    這篇文章主要介紹了Kotlin語(yǔ)言中CompileSdkVersion和targetSdkVersion有什么區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-02-02

最新評(píng)論