Android 官方推荐 : DialogFragment 创建对话框

奋斗吧
奋斗吧
擅长邻域:未填写

标签: Android 官方推荐 : DialogFragment 创建对话框 HarmonyOS博客 51CTO博客

2023-07-18 18:24:26 84浏览

Android 官方推荐 : DialogFragment 创建对话框,1、概述DialogFragment在android3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对


1、 概述


DialogFragment在android 3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。典型的用于:展示警告框,输入框,确认框等等。


在DialogFragment产生之前,我们创建对话框:一般采用AlertDialog和Dialog。注:官方不推荐直接使用Dialog创建对话框。


2、 好处与用法


使用DialogFragment来管理对话框,当旋转屏幕和按下后退键时可以更好的管理其声明周期,它和Fragment有着基本一致的声明周期。且DialogFragment也允许开发者把Dialog作为内嵌的组件进行重用,类似Fragment(可以在大屏幕和小屏幕显示出不同的效果)。上面会通过例子展示这些好处~


使用DialogFragment至少需要实现onCreateView或者onCreateDIalog方法。onCreateView即使用定义的xml布局文件展示Dialog。onCreateDialog即利用AlertDialog或者Dialog创建出Dialog。

3、 重写onCreateView创建Dialog

a)布局文件,我们创建一个设置名称的布局文件:

1. <?xml version="1.0" encoding="utf-8"?>  
2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3. android:layout_width="wrap_content"  
4. android:layout_height="wrap_content" >  
5.   
6. <TextView  
7. android:id="@+id/id_label_your_name"  
8. android:layout_width="wrap_content"  
9. android:layout_height="32dp"  
10. android:gravity="center_vertical"  
11. android:text="Your name:" />  
12.   
13. <EditText  
14. android:id="@+id/id_txt_your_name"  
15. android:layout_width="match_parent"  
16. android:layout_height="wrap_content"  
17. android:layout_toRightOf="@id/id_label_your_name"  
18. android:imeOptions="actionDone"  
19. android:inputType="text" />  
20.   
21. <Button  
22. android:id="@+id/id_sure_edit_name"  
23. android:layout_width="wrap_content"  
24. android:layout_height="wrap_content"  
25. android:layout_alignParentRight="true"  
26. android:layout_below="@id/id_txt_your_name"  
27. android:text="ok" />  
28.   
29. </RelativeLayout>


b)继承DialogFragment,重写onCreateView方法

c)测试运行:

1. package com.example.zhy_dialogfragment;  
2.   
3. import android.app.DialogFragment;  
4. import android.os.Bundle;  
5. import android.view.LayoutInflater;  
6. import android.view.View;  
7. import android.view.ViewGroup;  
8.   
9. public class EditNameDialogFragment extends DialogFragment  
10. {  
11.   
12.   
13. @Override  
14. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
15.             Bundle savedInstanceState)  
16.     {  
17.         View view = inflater.inflate(R.layout.fragment_edit_name, container);  
18. return view;  
19.     }  
20.   
21. }

Main方法中调用:


1. public void showEditDialog(View view)  
2.     {  
3. new EditNameDialogFragment();  
4. "EditNameDialog");  
5.     }

效果图:



Android 官方推荐 : DialogFragment 创建对话框_java


可以看到,对话框成功创建并显示出来,不过默认对话框有个讨厌的标题,我们怎么去掉呢:可以在onCreateView中调用getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);即可去掉。即:

1. public class EditNameDialogFragment extends DialogFragment  
2. {  
3.   
4. @Override  
5. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
6.             Bundle savedInstanceState)  
7.     {  
8.         getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);  
9.         View view = inflater.inflate(R.layout.fragment_edit_name, container);  
10. return view;  
11.     }  
12.   
13. }

效果图:



Android 官方推荐 : DialogFragment 创建对话框_Text_02



很完美的去掉了讨厌的标题。



4、 重写onCreateDialog创建Dialog

在onCreateDialog中一般可以使用AlertDialog或者Dialog创建对话框,不过既然google不推荐直接使用Dialog,我们就使用AlertDialog来创建一个登录的对话框。

a)布局文件

1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3. android:layout_width="wrap_content"  
4. android:layout_height="wrap_content"  
5. android:orientation="vertical" >  
6.   
7. <ImageView  
8. android:layout_width="match_parent"  
9. android:layout_height="64dp"  
10. android:background="#FFFFBB33"  
11. android:contentDescription="@string/app_name"  
12. android:scaleType="center"  
13. android:src="@drawable/title" />  
14.   
15. <EditText  
16. android:id="@+id/id_txt_username"  
17. android:layout_width="match_parent"  
18. android:layout_height="wrap_content"  
19. android:layout_marginBottom="4dp"  
20. android:layout_marginLeft="4dp"  
21. android:layout_marginRight="4dp"  
22. android:layout_marginTop="16dp"  
23. android:hint="input username"  
24. android:inputType="textEmailAddress" />  
25.   
26. <EditText  
27. android:id="@+id/id_txt_password"  
28. android:layout_width="match_parent"  
29. android:layout_height="wrap_content"  
30. android:layout_marginBottom="16dp"  
31. android:layout_marginLeft="4dp"  
32. android:layout_marginRight="4dp"  
33. android:layout_marginTop="4dp"  
34. android:fontFamily="sans-serif"  
35. android:hint="input password"  
36. android:inputType="textPassword" />  
37.   
38. </LinearLayout>



b)继承DialogFragment重写onCreateDialog方法

1. package com.example.zhy_dialogfragment;  
2.   
3. import android.app.AlertDialog;  
4. import android.app.Dialog;  
5. import android.app.DialogFragment;  
6. import android.content.DialogInterface;  
7. import android.os.Bundle;  
8. import android.view.LayoutInflater;  
9. import android.view.View;  
10. import android.view.ViewGroup;  
11. import android.widget.EditText;  
12.   
13. public class LoginDialogFragment extends DialogFragment  
14. {  
15.   
16. @Override  
17. public Dialog onCreateDialog(Bundle savedInstanceState)  
18.     {  
19. new AlertDialog.Builder(getActivity());  
20. // Get the layout inflater  
21.         LayoutInflater inflater = getActivity().getLayoutInflater();  
22. null);  
23. // Inflate and set the layout for the dialog  
24. // Pass null as the parent view because its going in the dialog layout  
25.         builder.setView(view)  
26. // Add action buttons  
27. "Sign in",  
28. new DialogInterface.OnClickListener()  
29.                         {  
30. @Override  
31. public void onClick(DialogInterface dialog, int id)  
32.                             {  
33.                             }  
34. "Cancel", null);  
35. return builder.create();  
36.     }  
37. }


c)调用

1. public void showLoginDialog(View view)  
2.     {  
3. new LoginDialogFragment();  
4. "loginDialog");  
5.     }


效果图:


Android 官方推荐 : DialogFragment 创建对话框_android_03

可以看到通过重写onCreateDialog同样可以实现创建对话框,效果还是很nice的。

5、传递数据给Activity

从dialog传递数据给Activity,可以使用“fragment interface pattern”的方式,下面通过一个改造上面的登录框来展示这种模式。

改动比较小,直接贴代码了:

1. package com.example.zhy_dialogfragment;  
2.   
3. import android.app.AlertDialog;  
4. import android.app.Dialog;  
5. import android.app.DialogFragment;  
6. import android.content.DialogInterface;  
7. import android.os.Bundle;  
8. import android.view.LayoutInflater;  
9. import android.view.View;  
10. import android.view.ViewGroup;  
11. import android.widget.EditText;  
12.   
13. public class LoginDialogFragment extends DialogFragment  
14. {  
15. private EditText mUsername;  
16. private EditText mPassword;  
17.   
18. public interface LoginInputListener  
19.     {  
20. void onLoginInputComplete(String username, String password);  
21.     }  
22.       
23. @Override  
24. public Dialog onCreateDialog(Bundle savedInstanceState)  
25.     {  
26. new AlertDialog.Builder(getActivity());  
27. // Get the layout inflater  
28.         LayoutInflater inflater = getActivity().getLayoutInflater();  
29. null);  
30.         mUsername = (EditText) view.findViewById(R.id.id_txt_username);  
31.         mPassword = (EditText) view.findViewById(R.id.id_txt_password);  
32. // Inflate and set the layout for the dialog  
33. // Pass null as the parent view because its going in the dialog layout  
34.         builder.setView(view)  
35. // Add action buttons  
36. "Sign in",  
37. new DialogInterface.OnClickListener()  
38.                         {  
39. @Override  
40. public void onClick(DialogInterface dialog, int id)  
41.                             {  
42.                                 LoginInputListener listener = (LoginInputListener) getActivity();  
43.                                 listener.onLoginInputComplete(mUsername  
44.                                         .getText().toString(), mPassword  
45.                                         .getText().toString());  
46.                             }  
47. "Cancel", null);  
48. return builder.create();  
49.     }  
50. }


拿到username和password的引用,在点击登录的时候,把activity强转为我们自定义的接口:LoginInputListener,然后将用户输入的数据返回。

MainActivity中需要实现我们的接口LoginInputListener,实现我们的方法,就可以实现当用户点击登陆时,获得我们的帐号密码了:

效果:

1. c)  MainActivity  
2. package com.example.zhy_dialogfragment;  
3.   
4. import com.example.zhy_dialogfragment.LoginDialogFragment.LoginInputListener;  
5.   
6. import android.app.Activity;  
7. import android.app.AlertDialog;  
8. import android.content.DialogInterface;  
9. import android.os.Bundle;  
10. import android.view.LayoutInflater;  
11. import android.view.View;  
12. import android.widget.Toast;  
13.   
14. public class MainActivity extends Activity implements LoginInputListener  
15. {  
16.   
17. @Override  
18. protected void onCreate(Bundle savedInstanceState)  
19.     {  
20. super.onCreate(savedInstanceState);  
21.         setContentView(R.layout.activity_main);  
22.     }  
23.   
24.       
25.   
26. public void showLoginDialog(View view)  
27.     {  
28. new LoginDialogFragment();  
29. "loginDialog");  
30.   
31.     }  
32.   
33. @Override  
34. public void onLoginInputComplete(String username, String password)  
35.     {  
36. this, "帐号:" + username + ",  密码 :" + password,  
37.                 Toast.LENGTH_SHORT).show();  
38.     }  
39.   
40. }


Android 官方推荐 : DialogFragment 创建对话框_Text_04

6、DialogFragment做屏幕适配

我们希望,一个对话框在大屏幕上以对话框的形式展示,而小屏幕上则直接嵌入当前的Actvity中。这种效果的对话框,只能通过重写onCreateView实现。下面我们利用上面的EditNameDialogFragment来显示。

EditNameDialogFragment我们已经编写好了,直接在MainActivity中写调用

1. public void showDialogInDifferentScreen(View view)  
2.     {  
3.         FragmentManager fragmentManager = getFragmentManager();  
4. new EditNameDialogFragment();  
5.   
6. boolean mIsLargeLayout = getResources().getBoolean(R.bool.large_layout) ;  
7. "TAG", mIsLargeLayout+"");  
8. if (mIsLargeLayout )  
9.         {  
10. // The device is using a large layout, so show the fragment as a  
11. // dialog  
12. "dialog");  
13. else  
14.         {  
15. // The device is smaller, so show the fragment fullscreen  
16.             FragmentTransaction transaction = fragmentManager  
17.                     .beginTransaction();  
18. // For a little polish, specify a transition animation  
19.             transaction  
20.                     .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);  
21. // To make it fullscreen, use the 'content' root view as the  
22. // container  
23. // for the fragment, which is always the root view for the activity  
24.             transaction.replace(R.id.id_ly, newFragment)  
25.                     .commit();  
26.         }  
27.     }


可以看到,我们通过读取R.bool.large_layout,然后根据得到的布尔值,如果是大屏幕则直接以对话框显示,如果是小屏幕则嵌入我们的Activity布局中

这个R.bool.large_layout是我们定义的资源文件:

在默认的values下新建一个bools.xml


1. <?xml version="1.0" encoding="utf-8"?>  
2. <resources>  
3.   
4. <bool name="large_layout">false</bool>  
5.   
6. </resources>



然后在res下新建一个values-large,在values-large下再新建一个bools.xml


    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <resources>  
    3.   
    4. <bool name="large_layout">true</bool>  
    5.   
    6. </resources>



    最后测试:


    Android 官方推荐 : DialogFragment 创建对话框_java_05

              

    Android 官方推荐 : DialogFragment 创建对话框_java_06

    左边为模拟器,右边为我的手机~~~~~

    7、屏幕旋转

    当用户输入帐号密码时,忽然旋转了一下屏幕,帐号密码不见了~~~是不是会抓狂

    传统的new AlertDialog在屏幕旋转时,第一不会保存用户输入的值,第二还会报异常,因为Activity销毁前不允许对话框未关闭。而通过DialogFragment实现的对话框则可以完全不必考虑旋转的问题。

    我们直接把上面登录使用AlertDialog创建的登录框,拷贝到MainActivity中直接调用:

      1. public void showLoginDialogWithoutFragment(View view)  
      2.     {  
      3. new AlertDialog.Builder(this);  
      4. // Get the layout inflater  
      5. this.getLayoutInflater();  
      6.   
      7. // Inflate and set the layout for the dialog  
      8. // Pass null as the parent view because its going in the dialog layout  
      9. null))  
      10. // Add action buttons  
      11. "Sign in",  
      12. new DialogInterface.OnClickListener()  
      13.                         {  
      14. @Override  
      15. public void onClick(DialogInterface dialog, int id)  
      16.                             {  
      17. // sign in the user ...  
      18.                             }  
      19. "Cancel", null).show();  
      20.     }



      下面我分别点击两种方式创建的登录框,看效果图:


      Android 官方推荐 : DialogFragment 创建对话框_android_07

      可以看到,传统的Dialog旋转屏幕时就消失了,且后台log会报异常~~~使用DialogFragment则不受影响。

      好了,关于DialogFragment的介绍结束~~~~

      有任何疑问请留言

      5c币

      源码点击下载

      参考文档:

      http://developer.android.com/guide/topics/ui/dialogs.html#DialogFragment

      https://github.com/thecodepath/android_guides/wiki/Using-DialogFragment

      好博客就要一起分享哦!分享海报

      此处可发布评论

      评论(0展开评论

      暂无评论,快来写一下吧

      展开评论

      您可能感兴趣的博客

      客服QQ 1913284695