许朋友爱玩资料

本文主要介绍许朋友爱玩资料 方法和在新技术下所面对的“挑战”,方便大家深入理解许朋友爱玩资料 过程。本文也将分享许朋友爱玩资料 所遇到的问题和应对策略,怎么解决怎么做的问题。
通过深入本文可以理解代码原理,进行代码文档的下载,也可以查看相应 Demo 部署效果。

你还在用 Dialog 吗? 你还在经常烦恼于屏幕翻转的时候,Dialog 的各种奇葩情况吗? 你想降低耦合吗? 如果你有其中的一个烦恼,那么恭喜你,遇见了 DialogFragment,他恰巧就解决了上面所说的问题,如果感兴趣的话,随笔者来看下吧!

前言

本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍:

我的 GIthub 博客

思维导图

许朋友爱玩

一、为什么要学习 DialogFragment

你还在用 Dialog 吗?

你还在经常烦恼于屏幕翻转的时候,Dialog 的各种奇葩情况吗?

你想降低耦合吗?

如果你有其中的一个烦恼,那么恭喜你,遇见了 DialogFragment ,他恰巧就解决了上面所说的问题,如果感兴趣的话,随笔者来看下吧!

许朋友爱玩

二、背景

Android 官方推荐使用 DialogFragment 来代替 Dialog ,可以让它具有更高的可复用性(降低耦合)和更好的便利性(很好的处理屏幕翻转的情况)。

而创建 DialogFragment 有两种方式:

  • 法一:覆写其 onCreateDialog 方法

一般用于创建替代传统Dialog 对话框的场景,UI 简单功能单一,不适用于使用了多线程(例如网络请求)的情况下(因为不能正确的获取当前 Fragment 的状态,会产生空指针异常)

  • 法二:覆写其 onCreateView 方法

一般用于创建复杂内容弹窗全屏展示效果的场景,UI 复杂功能复杂一般有网络请求等异步操作

许朋友爱玩

三、应用

3.1 基本用法是什么

法一:

a.创建一个简单的 Dialog 并返回它即可

@Override public Dialog onCreateDialog(Bundle savedInstanceState) {     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(); } 
许朋友爱玩
运行截图

b.你也可以使用自定义 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; } 
许朋友爱玩
运行截图

这种情况,标题内容上面的白色部分,其实是默认的标题栏,如果需要的话,可以设置隐藏标题栏(将在下文说到)

3.2 如何处理屏幕翻转

如果使用传统的 Dialog ,需要我们手动处理屏幕翻转的情况,但使用 DialogFragment 的话,则不需要我们进行任何处理,FragmentManager 会自动管理 DialogFragment 的生命周期。

3.3 如何隐藏标题栏

在基本用法里代码注释有设置主题的地方,下面详细说下两种方法下设置无标题栏的方式:

法一:

@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());     // 关闭标题栏,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(DialogFragment.STYLE_NO_TITLE, 0); } 

3.4 如何实现全屏

常用的形式大多是宽度上和屏幕一样宽,高度自适应,下面直接看代码:

法一:

@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     // 设置宽度为屏宽、位置靠近屏幕底部     Window window = dialog.getWindow();     //设置了窗口的背景色为透明,这一步是必须的     // <color name="transparent">#50000000</color>     window.setBackgroundDrawableResource(R.color.transparent);     WindowManager.LayoutParams wlp = window.getAttributes();     wlp.gravity = Gravity.BOTTOM;     //设置窗口的宽度为 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         // 设置宽度为屏宽、靠近屏幕底部。         final Window window = getDialog().getWindow();      //这步是必须的         window.setBackgroundDrawableResource(R.color.transparent);      //必要,设置 padding,这一步也是必须的,内容不能填充全部宽度和高度         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 应用场景的区别是什么

文章一开始简单总结了法一 和法二的应用场景,这里说明下:

  • 法一:为简单的替代 Dialog 提供了非常方便的创建方式,但是在使用了多线程(例如网络请求)的情况下,不能正确的获取当前 Fragment 的状态,会产生空指针异常
  • 法二:则没有如上空指针的问题,而且,其创建方式默认使用了自定义 View,更便于应对复杂 UI 的场景

3.6 如何与 Activity 进行交互?

使用回调的方式

a.在 DialogFragment 中:

public interface OnDialogListener {     void onDialogClick(String person); }  private OnDialogListener mlistener;  public void setOnDialogListener(OnDialogListener dialogListener){     this.mlistener = dialogListener; } 

DialogFragment 的点击事件中:

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 如何结合动画使用

a.设置从下到上弹出的动画

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.设置从上到下弹出的动画

private boolean isAnimation = false;//用来判断是否多次点击。防止多次执行  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) {             //用来判断是否多次点击。防止多次执行             isAnimation = false;             //弹框消失             IOSDialogFragment.this.dismiss();         }          @Override         public void onAnimationRepeat(Animation animation) {         }     }); } 

c.封装从上到下弹出的动画

加上判断是否多次点击。防止多次执行

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();         //第二个参数是 tag         fragment.show(getSupportFragmentManager(), "android");     } }); 

3.9 如何点击空白处时关闭的时候,还能使用动画?

直接对 DecorView 设置 onTouchListener

window.getDecorView().setOnTouchListener(new View.OnTouchListener() {     public boolean onTouch(View v, MotionEvent event) {         if (event.getAction() == MotionEvent.ACTION_UP) {             //弹框消失的动画执行相关代码             ....             ....                  }         return true;     } });  

四、结语

终于看完了鸭!累死鸭了!如果还有什么不是很清楚的话,可以看下笔者写的示例 Demo

许朋友爱玩

如果文章对您有一点帮助的话,希望您能点一下赞,您的点赞,是我前进的动力

本文参考链接:

  • 项目需求讨论-仿ios底部弹框实现及分析
  • 底部弹出DialogFragment+与Activity数据交互
  • Android 必知必会 – DialogFragment 使用总结

本文使用 mdnice 排版

许朋友爱玩资料部分资料来自网络,侵权毕设源码联系删除

区块链毕设网(www.qklbishe.com)全网最靠谱的原创区块链毕设代做网站
部分资料来自网络,侵权联系删除!
资源收费仅为搬运整理打赏费用,用户自愿支付 !
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台 » 许朋友爱玩资料

提供最优质的资源集合

立即查看 了解详情