亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

DialogFragment運(yùn)行原理及使用方法詳解

 更新時間:2020年10月29日 11:45:51   作者:入她  
這篇文章主要介紹了DialogFragment運(yùn)行原理及使用方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

思維導(dǎo)圖

一、為什么要學(xué)習(xí) DialogFragment

你還在用 Dialog 嗎?你還在經(jīng)常煩惱于屏幕翻轉(zhuǎn)的時候,Dialog 的各種奇葩情況嗎?你想降低耦合嗎?如果你有其中的一個煩惱,那么恭喜你,遇見了 DialogFragment ,他恰巧就解決了上面所說的問題,如果感興趣的話,隨筆者來看下吧!

二、背景

Android 官方推薦使用 DialogFragment 來代替 Dialog ,可以讓它具有更高的可復(fù)用性(降低耦合)和更好的便利性(很好的處理屏幕翻轉(zhuǎn)的情況)。而創(chuàng)建 DialogFragment 有兩種方式:

「法一:覆寫其 onCreateDialog 方法」

一般用于創(chuàng)建替代傳統(tǒng)的 Dialog 對話框的場景,UI 簡單,功能單一,不適用于使用了多線程(例如網(wǎng)絡(luò)請求)的情況下(因?yàn)椴荒苷_的獲取當(dāng)前 Fragment 的狀態(tài),會產(chǎn)生空指針異常)

「法二:覆寫其 onCreateView 方法」

一般用于創(chuàng)建復(fù)雜內(nèi)容彈窗或全屏展示效果的場景,UI 復(fù)雜,功能復(fù)雜,一般有網(wǎng)絡(luò)請求等異步操作

三、應(yīng)用

3.1 基本用法是什么

法一:

a.創(chuàng)建一個簡單的 Dialog 并返回它即可

@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);
  builder.setTitle("注意:")
      .setMessage("是否退出應(yīng)用?")
      .setPositiveButton("確定", null)
      .setNegativeButton("取消", null)
      .setCancelable(false);
      //builder.show(); // 不能在這里使用 show() 方法
  return builder.create();
}

b.你也可以使用自定義 View 來創(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 的方式有多種,比如下面這種,使用時略有差異,需要自己注意:

@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;
}

這種情況,標(biāo)題內(nèi)容上面的白色部分,其實(shí)是默認(rèn)的標(biāo)題欄,如果需要的話,可以設(shè)置隱藏標(biāo)題欄(將在下文說到)

3.2 如何處理屏幕翻轉(zhuǎn)

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

3.3 如何隱藏標(biāo)題欄

在基本用法里代碼注釋有設(shè)置主題的地方,下面詳細(xì)說下兩種方法下設(shè)置無標(biāo)題欄的方式:法一:

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
  LayoutInflater inflater = Objects.requireNonNull(getActivity()).getLayoutInflater();
  @SuppressLint("InflateParams") View view = inflater.inflate(R.layout.fragment_i_o_s_dialog, null);
  Dialog dialog = new Dialog(getActivity());
  // 關(guān)閉標(biāo)題欄,setContentView() 之前調(diào)用
  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(DialogFragment.STYLE_NO_TITLE, 0);
}

3.4 如何實(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(), 0);
  dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
  dialog.setContentView(view);
  dialog.setCanceledOnTouchOutside(true);
  //Do something
  // 設(shè)置寬度為屏寬、位置靠近屏幕底部
  Window window = dialog.getWindow();
  //設(shè)置了窗口的背景色為透明,這一步是必須的
  // <color name="transparent">#50000000</color>
  window.setBackgroundDrawableResource(R.color.transparent);
  WindowManager.LayoutParams wlp = window.getAttributes();
  wlp.gravity = Gravity.BOTTOM;
  //設(shè)置窗口的寬度為 MATCH_PARENT,效果是和屏幕寬度一樣大
  wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
  wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
  window.setAttributes(wlp);
  return dialog;
}

法二:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setStyle(DialogFragment.STYLE_NO_TITLE, 0);
}

@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);
   //必要,設(shè)置 padding,這一步也是必須的,內(nèi)容不能填充全部寬度和高度
    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;
}

3.5 應(yīng)用場景的區(qū)別是什么

文章一開始簡單總結(jié)了法一 和法二的應(yīng)用場景,這里說明下:

法一:為簡單的替代 Dialog 提供了非常方便的創(chuàng)建方式,但是在使用了多線程(例如網(wǎng)絡(luò)請求)的情況下,不能正確的獲取當(dāng)前 Fragment 的狀態(tài),會產(chǎn)生空指針異常法二:則沒有如上空指針的問題,而且,其創(chuàng)建方式默認(rèn)使用了自定義 View,更便于應(yīng)對復(fù)雜 UI 的場景

3.6 如何與 Activity 進(jìn)行交互?

使用回調(diào)的方式

a.在 DialogFragment 中:

public interface OnDialogListener {
  void onDialogClick(String person);
}

private OnDialogListener mlistener;

public void setOnDialogListener(OnDialogListener dialogListener){
  this.mlistener = dialogListener;
}

在 DialogFragment 的點(diǎn)擊事件中:

public OnDialogListener mlistener;
@Override
public void onClick(View view) {
  switch (view.getId()) {
    case R.id.tv1:
      mlistener.onDialogClick("1");
      dismiss();
      break; 
    case R.id.tv2:
      mlistener.onDialogClick("2");
      dismiss();
      break;
    case R.id.tv3:
      mlistener.onDialogClick("3");
      dismiss();
      break;
    case R.id.tv4:
      mlistener.onDialogClick("4");
      dismiss();
      break;
  }
}

b.在 Activity 中

dialogFragment.setOnDialogListener(new PersonDialogFragment.OnDialogListener() {
  @Override
  public void onDialogClick(String person) {
    ToastUtil.showToast(person);
  }
});

3.7 如何結(jié)合動畫使用 a.設(shè)置從下到上彈出的動畫

private void slideToUp(View view) {
  Animation slide = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0);
  slide.setDuration(400);
  slide.setFillEnabled(true);
  slide.setFillAfter(true);
  view.startAnimation(slide);
}

b.設(shè)置從上到下彈出的動畫

private boolean isAnimation = false;//用來判斷是否多次點(diǎn)擊。防止多次執(zhí)行

public void slideToDown(View view) {
  Animation slide = new TranslateAnimation(
      Animation.RELATIVE_TO_SELF, 0.0f,
      Animation.RELATIVE_TO_SELF, 0.0f, 
      Animation.RELATIVE_TO_SELF, 0.0f,
      Animation.RELATIVE_TO_SELF, 1.0f);
  slide.setDuration(400);
  slide.setFillEnabled(true);
  slide.setFillAfter(true);
  view.startAnimation(slide);
  slide.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
    }

    @Override
    public void onAnimationEnd(Animation animation) {
      //用來判斷是否多次點(diǎn)擊。防止多次執(zhí)行
      isAnimation = false;
      //彈框消失
      IOSDialogFragment.this.dismiss();
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }
  });
}

c.封裝從上到下彈出的動畫

加上判斷是否多次點(diǎn)擊。防止多次執(zhí)行

private void dialogFinish() {
  if (isAnimation) {
    return;
  }
  isAnimation = true;
  slideToDown(rootView);
}

3.8 如何在 Activity 彈出 DialogFragment ?

mBtn.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    IOSDialogFragment fragment = new IOSDialogFragment();
    //第二個參數(shù)是 tag
    fragment.show(getSupportFragmentManager(), "android");
  }
});

3.9 如何點(diǎn)擊空白處時關(guān)閉的時候,還能使用動畫?

直接對 DecorView 設(shè)置 onTouchListener

window.getDecorView().setOnTouchListener(new View.OnTouchListener() {
  public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_UP) {
      //彈框消失的動畫執(zhí)行相關(guān)代碼
      ....
      ....
    
    }
    return true;
  }
});

四、結(jié)語

終于看完了鴨!累死鴨了!如果還有什么不是很清楚的話,可以看下筆者寫的示例 Demo

https://github.com/LoveLifeEveryday/TestDialogFragment

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論