Dialog, DialogFragment, PopupWindow比较

2024-04-25 07:32

本文主要是介绍Dialog, DialogFragment, PopupWindow比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

随着Fragment这个类的引 入,Google官方推荐大家使用DialogFragment来代替传统的Dialog.

1,AlertDialog与DialogFragment

before:

AlertDialog dialog = new AlertDialog.Builder(this).setTitle("Dialog").setMessage("thisis a dialog").show();

使用AlertDialog时如果屏幕方向发生变化,就会导致Activity重建,然后之前显示的对话框就不见了.
会产生如下报错:
04-1917:30:06.999: E/WindowManager(14495): Activitycom.example.androidtest.MainActivity has leaked windowcom.android.internal.policy.impl.PhoneWindow$DecorView{42ca3c18 V.E…..R……. 0,0-1026,414} that was originally added here

如果我们想要在旋转屏幕的时候也能保证这个对话框显示就需要做一定的处理了,在activity要销毁前设立一个标志,看这时对话框是否是显示状态,如果是那么activity在下次建立时直接显示对话框。
这么干:

@Override
protected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);if (dialog != null && dialog.isShowing()) {outState.putBoolean("DIALOG_SHOWN", true);}
}@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (savedInstanceState != null) {boolean isShown = savedInstanceState.getBoolean("DIALOG_SHOWN");if (isShown) {AlertDialog dialog = new AlertDialog.Builder(this).setTitle("Dialog").setMessage("thisis a dialog").show();}}
……
}

after:
若使用DialogFragment,当你旋转屏幕的时候,fragmentManager会自动管理DialogFragment的生命周期.

主要优势是旋转屏幕和按下后退键时可以更好的管理其声明周期;
还可以直接内嵌在activity界面中使用;
次要优势是使用AlertDialog,需要手写监听器positiveListener和negativeListener.代码不简洁.

怎么使用DialogFragment?

创建一个fragment,让其继承自DialogFragment,在onCreatView中通过布局文件建立View.
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
普通的fragment:
fragment是这么使用的:
① 建立FragmentManager对象,用来管理fragment
② 建立fragmentTransaction对象,用来添加和fragment
③ 提交fragment切换(commit)
DialogFragment的show方法里合着用:

public void show(FragmentManager manager, String tag){mDismissed = false; mShownByMe = true; FragmentTransaction ft = manager.beginTransaction(); // creat a fragmentTransactionft.add(this, tag); // add fragment with tagft.commit(); 
} public int show(FragmentTransaction transaction, String tag) {mDismissed = false; mShownByMe = true; transaction.add(this, tag); mViewDestroyed = false; mBackStackId = transaction.commit();return mBackStackId; 
}  public void dismiss() {  
dismissInternal(false);  
}  void dismissInternal(boolean allowStateLoss) {  
if (mDismissed) {  return;  
}  
mDismissed = true;  
mShownByMe = false;  
if (mDialog != null) {  mDialog.dismiss();  mDialog = null;  
}  
mViewDestroyed = true;  
//一个DialogFragment关闭的时候会检查堆栈里面有没有其他的对象,如果有就pop出来,如果没有就直接remove和commit
if (mBackStackId >= 0) {  //如果back stack堆栈有该Dialog,将其pop出来getFragmentManager().popBackStack(mBackStackId,  FragmentManager.POP_BACK_STACK_INCLUSIVE);  mBackStackId = -1;  
} else {  FragmentTransaction ft = getFragmentManager().beginTransaction();  ft.remove(this);   if (allowStateLoss) {  ft.commitAllowingStateLoss();  } else {  ft.commit();  }  
}  
}  

信息保存

如果你测试的手机被奇葩的定制了,那就乖乖的保存数据吧。

public class MyDialogFragment extends DialogFragment {EditText editText;@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.dialog, null);editText = (EditText) rootView.findViewById(R.id.editText);if (savedInstanceState != null) {CharSequence text = savedInstanceState.getCharSequence("input data");editText.setText(text == null ? "" : text);}return rootView;
}@Override
public void onSaveInstanceState(Bundle outState) {outState.putCharSequence("input data", editText.getText());super.onSaveInstanceState(outState);
}
}

通过onCreateDialog()来快捷的建立对话框

千万别同时使用onCreatView和onCreatDialog方法,他们仅仅是为了完成同样一个目的的两条路而已。

PS:从生命周期的顺序而言,先执行onCreateDialog(),后执行onCreateView().

在onCreatDialog建立一个警告对话框的builder,通过这个builder的create()方法来生成一个AlertDialog对象,因为AlertDialog是Dialog的子类,所以可以直接返回给Dialog。

public class MyDialogFragment extends DialogFragment implements android.content.DialogInterface.OnClickListener{@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {Builder builder = new AlertDialog.Builder(getActivity());builder.setTitle("用户申明").setMessage(getResources().getString(R.string.hello_world)).setPositiveButton("我同意", this).setNegativeButton("不同意", this).setCancelable(false);//.show(); // show cann't be use herereturn builder.create();
}@Override
public void onClick(DialogInterface dialog, int which) {// TODO 自动生成的方法存根
}
}

2,PopupWindow vs. Dialog

[stackoverflow]http://stackoverflow.com/questions/13827138/android-popupwindow-vs-dialogfragment
AlertDialog和Popupwindow的区别:
1)AlertDialog是非阻塞线程的,Popupwindow是阻塞线程的。
2)Dialog没法设置宽为整个屏幕宽,总有点边界。Popupwindow可以。

(1)Popupwindow在显示之前一定要设置宽高,Dialog无此限制。
(2)Popupwindow默认不会响应物理键盘的back,除非显示设置了popup.setFocusable(true);而在点击back的时候,Dialog会消失。
(3)Popupwindow不会给页面其他的部分添加蒙层,而Dialog会。
(4)Popupwindow没有标题,Dialog默认有标题,可以通过dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);取消标题
(5)二者显示的时候都要设置Gravity。如果不设置,Dialog默认是Gravity.CENTER。
(6)二者都有默认的背景,都可以通过setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));去掉。

其中最本质的差别就是:AlertDialog是非阻塞式对话框:AlertDialog弹出时,后台还可以做事情;而PopupWindow是阻塞式对话框:PopupWindow弹出时,程序会等待,在PopupWindow退出前,程序一直等待,只有当我们调用了dismiss方法的后,PopupWindow退出,程序才会向下执行。

Android 官方推荐 : DialogFragment 创建对话框 by HONGYANG on 2014-07-15.
摘自详细解读DialogFragment.
android中Dialog和PopupWindow的区别
Dialog和PopUpWindow的抉择
When to use Android PopupWindow vs Dialog

这篇关于Dialog, DialogFragment, PopupWindow比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/934052

相关文章

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

对postgresql日期和时间的比较

《对postgresql日期和时间的比较》文章介绍了在数据库中处理日期和时间类型时的一些注意事项,包括如何将字符串转换为日期或时间类型,以及在比较时自动转换的情况,作者建议在使用数据库时,根据具体情况... 目录PostgreSQL日期和时间比较DB里保存到时分秒,需要和年月日比较db里存储date或者ti

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

关键字synchronized、volatile的比较

关键字volatile是线程同步的轻量级实现,所以volatile性能肯定比synchronized要好,并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。随着JDK新版本的发布,synchronized关键字的执行效率上得到很大提升,在开发中使用synchronized关键字的比率还是比较大的。多线程访问volatile不会发生阻塞,而synchronize

stl的sort和手写快排的运行效率哪个比较高?

STL的sort必然要比你自己写的快排要快,因为你自己手写一个这么复杂的sort,那就太闲了。STL的sort是尽量让复杂度维持在O(N log N)的,因此就有了各种的Hybrid sort algorithm。 题主你提到的先quicksort到一定深度之后就转为heapsort,这种是introsort。 每种STL实现使用的算法各有不同,GNU Standard C++ Lib

研究生生涯中一些比较重要的网址

Mali GPU相关: 1.http://malideveloper.arm.com/resources/sdks/opengl-es-sdk-for-linux/ 2.http://malideveloper.arm.com/resources/tools/arm-development-studio-5/ 3.https://www.khronos.org/opengles/sdk/do

性能测试工具 wrk,ab,locust,Jmeter 压测结果比较

前言 在开发服务端软件时,经常需要进行性能测试,一般我采用手写性能测试代码的方式进行测试,那有什么现成的好的性能测试工具吗? 性能测试工具 wrk,ab,locust,Jmeter 压测结果比较 详见: 性能测试工具 wrk,ab,locust,Jmeter 压测结果比较 Jmeter性能测试 入门

MongoDB学习—(6)MongoDB的find查询比较符

首先,先通过以下函数向BookList集合中插入10000条数据 function insertN(obj,n){var i=0;while(i<n){obj.insert({id:i,name:"bookNumber"+i,publishTime:i+2000})i++;}}var BookList=db.getCollection("BookList")调用函数,这样,BookList

超声波清洗机哪个品牌比较好一点的?清洁力强的超声波清洗机品牌

随着生活水平的不断提升和幸福感的增强,珠宝、饰品和眼镜等物品已成为许多家庭的常备之物。然而,这些贵重细小的物件易于积聚微尘与隐形细菌,长此以往可能悄悄影响家人的健康,毕竟细菌是肉眼难以察觉的隐患。超声波清洗机应运而生,它以高科技手段有效地解决了这一隐忧,深层清洁,守护家人免受微小污染物的潜在威胁。不过现在市面上超声波清洗机品牌挺多的,究竟有哪些品牌的超声波清洗机比较好一点呢?接下来就为大家带来四款

【JavaScript】版本号和日期时间的比较

JS使用 ‘>’ 运算符比较两个字符串大小时,会把字符串转换为ASCII码依次比较。 比较标准时间格式可以直接使用 ’ > ’ 比较; (2018-07-20格式)