详解Android应用中DialogFragment的基本用法

DialogFragment的基本用法
1. 创建DialogFragment

public class DialogA extends DialogFragment implements DialogInterface.OnClickListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(R.string.dialoga_title) .setPositiveButton(R.string.ok, this) .setNegativeButton(R.string.cancel, this); return builder.create(); } @Override public void onClick(DialogInterface dialog, int id) { switch(id) { case AlertDialog.BUTTON_NEGATIVE: Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show(); break; case AlertDialog.BUTTON_POSITIVE: Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show(); break; default: break; } } }

说明:自定义一个DialogFragment,并重写它的onCreateDialog()方法。
2. 调用该DialogFragment
下面是在FragmentActivity中调用该DialogFragment对话框。

public class DialogTest extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); showDialog(); } private void showDialog() { FragmentManager fm = getSupportFragmentManager(); DialogA dialoga = new DialogA(); dialoga.show(fm, "fragmenta"); } }

自定义DialogFragment布局
下面介绍自定义DialogFragment的布局的方法
点击查看:自定义DialogFragment布局的完整代码
1. 设置布局文件

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/dialoga_intro" /> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_action_video" /> </LinearLayout>

2. 使用布局

public class DialogA extends DialogFragment implements DialogInterface.OnClickListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); LayoutInflater inflater = getActivity().getLayoutInflater(); builder.setView(inflater.inflate(R.layout.dialoga, null)) .setMessage(R.string.dialoga_title) .setPositiveButton(R.string.ok, this) .setNegativeButton(R.string.cancel, this); return builder.create(); } @Override public void onClick(DialogInterface dialog, int id) { switch(id) { case AlertDialog.BUTTON_NEGATIVE: Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show(); break; case AlertDialog.BUTTON_POSITIVE: Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show(); break; default: break; } } }

DialogFragment和Activity的交互
下面介绍自定义DialogFragment和Activity交互的方法
点击查看:DialogFragment和Activity交互的完整代码
1. 定义通信接口
在DialogFragment中定义它们之间的通信接口。

public interface NoticeDialogListener { public void onDialogPositiveClick(DialogFragment dialog); public void onDialogNegativeClick(DialogFragment dialog); } // Use this instance of the interface to deliver action events NoticeDialogListener mListener; // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener @Override public void onAttach(Activity activity) { super.onAttach(activity); // Verify that the host activity implements the callback interface try { // Instantiate the NoticeDialogListener so we can send events to the host mListener = (NoticeDialogListener) activity; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(activity.toString() + " must implement NoticeDialogListener"); } }

2. 在DialogFragment中调用该接口

@Override public void onClick(DialogInterface dialog, int id) { switch(id) { case AlertDialog.BUTTON_POSITIVE: //Toast.makeText(getActivity(), "Negative", Toast.LENGTH_SHORT).show(); mListener.onDialogPositiveClick(DialogA.this); break; case AlertDialog.BUTTON_NEGATIVE: //Toast.makeText(getActivity(), "Positive", Toast.LENGTH_SHORT).show(); mListener.onDialogNegativeClick(DialogA.this); break; default: break; } }

3. 在Activity中实现该接口

public class DialogTest extends FragmentActivity implements DialogA.NoticeDialogListener { ... @Override public void onDialogPositiveClick(DialogFragment dialog) { Toast.makeText(this, "Positive Callback", Toast.LENGTH_SHORT).show(); } @Override public void onDialogNegativeClick(DialogFragment dialog) { Toast.makeText(this, "Negative Callback", Toast.LENGTH_SHORT).show(); } }

Dialog与DialogFragment的对比
从代码的编写角度看,Dialog使用起来要更为简单,但是Google则是推荐尽量使用DialogFragment(对于Android 3.0以下的版本,可以结合使用support包中提供的DialogFragment以及FragmentActivity)。今天试着用这两种方式来创建对话框,发现DialogFragment果然有一个非常好的特性(在手机配置变化,导致Activity需要重新创建时,例如旋屏,基于DialogFragment的对话框将会由FragmentManager自动重建,然而基于Dialog实现的对话框则没有这样的能力)。

下面是两段实例代码:

他们使用的界面都一样:(dialog.xml)

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> </LinearLayout>

1.基于Dialog实现的对话框

public class MainActivity extends Activity { private Button clk; private Dialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); clk = (Button) findViewById(R.id.clk); dialog = new Dialog(this); dialog.setContentView(R.layout.dialog); clk.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { dialog.show(); } }); } }

当我们点击按钮时,会弹出对话框(内容为android logo),当我们旋转屏幕后,Activity重新创建,整个Activity的界面没有问题,而对话框消失了。
除此之外,其实还有一个问题,就是在logcat中会看到异常信息:Android..leaked .. window,这是因为在Activity结束之前,Android要求所有的Dialog必须要关闭。我们旋屏后,Activity会被重建,而上面的代码逻辑并没有考虑到对话框的状态以及是否已关闭。

于是将上述代码修改为:

public class MainActivity extends Activity { private Button clk; private Dialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); clk = (Button) findViewById(R.id.clk); dialog = new Dialog(this); dialog.setContentView(R.layout.dialog); clk.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { dialog.show(); } }); //用户恢复对话框的状态 if(savedInstanceState != null && savedInstanceState.getBoolean("dialog_show")) clk.performClick(); } /** * 用于保存对话框的状态以便恢复 */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if(dialog != null && dialog.isShowing()) outState.putBoolean("dialog_show", true); else outState.putBoolean("dialog_show", false); } /** * 在Activity销毁之前,确保对话框以关闭 */ @Override protected void onDestroy() { super.onDestroy(); if(dialog != null && dialog.isShowing()) dialog.dismiss(); } }

2. 基于DialogFragment的对话框

与上面的对话框使用同样的界面布局,此处仅仅展现一个简单对话框,因此只重写了onCreateView方法

public class MyDialogFragment extends DialogFragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.dialog, container, false); return v; } } public class MainActivity extends FragmentActivity { private Button clk; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); clk = (Button) findViewById(R.id.clk); clk.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { MyDialogFragment mdf = new MyDialogFragment(); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); mdf.show(ft, "df"); } }); } }

这两段代码可以实现第一种方式的同样功能,此处我们并没有去关心对话框的重建,以及Activity销毁前对话框是否已关闭,这一切都是由FragmentManager来管理。
其实DialogFragment还拥有fragment的优点,即可以在一个Activity内部实现回退(因为FragmentManager会管理一个回退栈)

时间: 2024-10-24 17:19:12

详解Android应用中DialogFragment的基本用法的相关文章

详解Android应用中DialogFragment的基本用法_Android

DialogFragment的基本用法 1. 创建DialogFragment public class DialogA extends DialogFragment implements DialogInterface.OnClickListener { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder

详解Linux系统中md5sum命令的用法

  这篇文章主要介绍了详解Linux系统中md5sum命令的用法,用来处理MD5验证的相关操作,需要的朋友可以参考下 MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改.MD5全称是报文摘要算法(Message-Digest Algorithm 5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的"指纹"(或称"报文摘要"),不同的文件产生相 同的报文摘要的可能性是非常非常之小的. 在linux或Unix上,

详解Android TableLayout中stretchColumns、shrinkColumns的用法

详解Android 中TableLayout中stretchColumns.shrinkColumns的用法 android:stretchColumns="1" android:shrinkColumns="1"这两个属性是TableLayout所特有的,也是这两个属性影响了子对象的布局. 表格布局是按照行列来组织子视图的布局.表格布局包含一系列的Tabrow对象,用于定义行(也可以使用其它子对象).表格布局不为它的行.列和单元格显示表格线.每个行可以包含个以上(

详解Android开发中Fragment的使用_java

前言学习Java和Android将近一年的时间了,期间的成果应该就是独立完成了一个Android客户端,并且保证了其在主线版本的稳定性.期间遇到了很多坑,也跟着师兄学到了很多Android知识.但是人总是要拥抱变化,不能让自己太安逸,虽然有不舍,但是我已经证明了自己的学习能力,下一步就是开始做Rom Porting了.这里总结一下之前项目中用到最多的Fragment. Fragment简介Fragment可以理解成Activity中用户界面的一个行为或者一部分,它必须被嵌套在Activity中.

详解Android应用中使用TabHost组件进行布局的基本方法_Android

TabHost布局文件 我们先来了解一下布局文件的基本内容:1. 根标签及id 设置Android自带id : XML布局文件中, 可以使用 标签设置, 其中的id 需要引用 android的自带id : android:id=@android:id/tabhost ; getHost()获取前提 : 设置了该id之后, 在Activity界面可以使用 getHost(), 获取这个TabHost 视图对象; 示例 : 复制代码 代码如下: <tabhost android:id="@an

详解Android应用中preference首选项的编写方法_Android

最近学习android时发现,很多书上都介绍了preference首选项这个东西,但是大部分的书都是直接上来讲怎么用,对其的用途和来历都是只字不提,笔者本人对于这种做法是非常鄙视的. 这里,我将对其进行一点简单的描述,可能说法并不严谨,但是至少能帮助你理解到底什么事首选项: 首选项这个词是preference翻译过来的,至于它到底是什么,我用一句话概括下:preference是一种android为我们提供的方便的对数据进行存储的工具. 分析这句话: 首先,我们明确,preference是和数据存

详解Android开发中Activity的四种launchMode_Android

Activity栈主要用于管理Activity的切换.当使用Intent跳转至某个目标Activity,需要根据目标Activity的加载模式来加载. Activity一共有以下四种launchMode: 1.standard:默认,每次使用Intent跳转到目标Activity时都创建一个新的实例.坏处是每次进入都要创建新的实例,执行OnCreate方法. 2.singleTop:如果要跳转的目标Activity正好在task的顶部(说明当前肯定不在目标task里,例如我在微信首页,然后想使用

详解Android App中使用VideoView来实现视频播放的方法_Android

通过VideoView播放视频的步骤: 1.在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件 2.调用VideoView的如下两个方法来加载指定的视频 (1)setVidePath(String path):加载path文件代表的视频 (2)setVideoURI(Uri uri):加载uri所对应的视频 3.调用VideoView的start().stop().psuse()方法来控制视频的播放 VideoView通过与MediaController类结合使用,

详解Android App中的AsyncTask异步任务执行方式_Android

基本概念 AsyncTask:异步任务,从字面上来说,就是在我们的UI主线程运行的时候,异步的完成一些操作.AsyncTask允许我们的执行一个异步的任务在后台.我们可以将耗时的操作放在异步任务当中来执行,并随时将任务执行的结果返回给我们的UI线程来更新我们的UI控件.通过AsyncTask我们可以轻松的解决多线程之间的通信问题. 怎么来理解AsyncTask呢?通俗一点来说,AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架,其介于Thread和Handler之间,我