Android 对话框片段

在本教程中,我们将讨论什么是DialogFragments。我们将通过一个简单的安卓应用程序来了解它们与Dialogs的不同之处。

Androad# Dialogments

DialogFragment是扩展Fragment类的实用程序类。它是v4支持库的一部分,用于在位于其余内容顶部的活动中显示覆盖模式窗口。本质上,DialogFragment显示一个对话框,但在片段内。

Google建议我们在活动中使用DialogFragment,而不是简单的Alert Dialog生成器。

为什么会这样?

  • DialogFragments有自己的生命周期方法。因此,该活动没有告诉对话框要做什么的责任。
  • 不再有 IlLegalStateExceptions** 和泄漏的窗口崩溃。当活动在警报对话框仍在的情况下被销毁时,这种情况非常常见。

因为DialogFragment是一个片段,所以它集成到活动的生命周期中,并确保对话框窗口中发生的事情保持一致。在Android应用程序中使用DialogFragments创建对话框是一种很好的做法。您的类必须扩展DialogFragment,并至少实现onCreateDialog和/或onCreateView。可以通过两种方式使用DialogFragment创建对话框:

  • onCreateDialog-在这里可以使用AlertDialog.Builder类创建AlertDialog。
  • onCreateView-在这里您可以使用定义的自定义视图创建一个Dialog。

为了创建显示对话框的DialogFragment,我们需要在DialogFragment实例上调用方法show(),如下所示:

1MyDialogFragment dialogFragment = new MyDialogFragment();
2FragmentTranscation ft = getSupportFragmentManager().beginTransaction();
3Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
4if (prev != null) {
5   ft.remove(prev);
6}
7ft.addToBackStack(null);
8dialogFragment.show(ft, "dialog");

我们可以将任何标签设置为show()的第二个参数。为了创建将对话框嵌入到片段中的DialogFragment,我们只需像处理任何Fragment.一样将片段添加到Framelayout中

你知道吗您也可以在Fragments中显示自定义视图,而不仅仅是Dialog。

实例化DialogFragment类时。方法按以下顺序调用:

  • onCreate
  • online对话框
  • onCreateView
  • onViewCreated
  • onDestroy

往返于DialogFragment的数据

为了将数据传递给DialogFragment类,我们只需在类的实例上使用setArguments设置数据即可。为了将来自DialogFragments的数据返回到Activity/另一个片段,我们需要创建自定义接口。在下一节中,我们将创建一个Android应用程序,该应用程序执行以下操作:

  • 创建简单的DialogFragment对话框
  • 活动中嵌入的对话框片段
  • 有风格的DialogFragment。
  • 返回数据的DialogFragment

项目结构

android dialogfragment项目

代码

activity_main.xml类的代码如下所示:

 1<?xml version="1.0" encoding="utf-8"?>
 2<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    xmlns:tools="https://schemas.android.com/tools"
 4    android:layout_width="match_parent"
 5    android:layout_height="match_parent"
 6    android:orientation="vertical"
 7    tools:context=".MainActivity">
 8
 9    <FrameLayout
10        android:id="@+id/frameLayout"
11        android:layout_width="match_parent"
12        android:layout_height="wrap_content"
13        android:layout_above="@+id/btnEmbedDialogFragment"
14        android:layout_alignParentTop="true" />
15
16    <Button
17        android:id="@+id/btnEmbedDialogFragment"
18        android:layout_width="wrap_content"
19        android:layout_height="wrap_content"
20        android:layout_centerHorizontal="true"
21        android:layout_above="@+id/btnDialogFragment"
22        android:text="EMBED DIALOG FRAGMENT" />
23
24    <Button
25        android:id="@+id/btnDialogFragment"
26        android:layout_width="wrap_content"
27        android:layout_height="wrap_content"
28        android:layout_centerInParent="true"
29        android:layout_marginTop="8dp"
30        android:text="SIMPLE DIALOG FRAGMENT" />
31
32    <Button
33        android:id="@+id/btnDialogFragmentFullScreen"
34        android:layout_width="wrap_content"
35        android:layout_height="wrap_content"
36        android:layout_below="@+id/btnDialogFragment"
37        android:layout_centerHorizontal="true"
38        android:layout_marginTop="8dp"
39        android:text="DIALOG FRAGMENT FULL SCREEN" />
40
41    <Button
42        android:id="@+id/btnAlertDialogFragment"
43        android:layout_width="wrap_content"
44        android:layout_height="wrap_content"
45        android:layout_below="@+id/btnDialogFragmentFullScreen"
46        android:layout_centerHorizontal="true"
47        android:layout_marginTop="8dp"
48        android:text="Alert Dialog Fragment" />
49
50    <TextView
51        android:id="@+id/textView"
52        android:layout_width="wrap_content"
53        android:layout_height="wrap_content"
54        android:layout_below="@+id/btnAlertDialogFragment"
55        android:layout_centerHorizontal="true" />
56
57</RelativeLayout>

每个按钮都会启动不同类型的DialogFragment。DialogFragment的自定义视图的XML布局在Fragment_Sample_Dialog.xml文件中定义,如下所示:

 1<?xml version="1.0" encoding="utf-8"?>
 2<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
 3    android:layout_width="match_parent"
 4    android:layout_height="match_parent"
 5    android:orientation="vertical"
 6    android:padding="10dp">
 7
 8    <TextView
 9        android:id="@+id/title"
10        android:layout_width="wrap_content"
11        android:layout_height="wrap_content"
12        android:layout_margin="16dp"
13        android:text="Please enter your username and password" />
14
15    <EditText
16        android:id="@+id/inEmail"
17        android:layout_width="match_parent"
18        android:layout_height="wrap_content"
19        android:hint="Email Address"
20        android:inputType="textEmailAddress" />
21
22    <EditText
23        android:id="@+id/inPassword"
24        android:layout_width="match_parent"
25        android:layout_height="wrap_content"
26        android:hint="Password"
27        android:inputType="textPassword" />
28
29    <Button
30        android:id="@+id/btnDone"
31        android:layout_width="match_parent"
32        android:layout_height="wrap_content"
33        android:text="Done" />
34</LinearLayout>

因此,我们的对话框将显示一个基本的登录表单。MainActivity.java的代码如下所示:

  1package com.journaldev.androiddialogfragment;
  2
  3import android.support.v4.app.Fragment;
  4import android.support.v4.app.FragmentTransaction;
  5import android.support.v7.app.AppCompatActivity;
  6import android.os.Bundle;
  7import android.text.TextUtils;
  8import android.view.View;
  9import android.widget.Button;
 10import android.widget.TextView;
 11
 12public class MainActivity extends AppCompatActivity implements View.OnClickListener, MyDialogFragment.DialogListener {
 13
 14    Button btnEmbedDialogFragment, btnDialogFragment, btnDialogFragmentFullScreen, btnAlertDialogFragment;
 15    TextView textView;
 16
 17    @Override
 18    protected void onCreate(Bundle savedInstanceState) {
 19        super.onCreate(savedInstanceState);
 20        setContentView(R.layout.activity_main);
 21
 22        textView = findViewById(R.id.textView);
 23        btnEmbedDialogFragment = findViewById(R.id.btnEmbedDialogFragment);
 24        btnDialogFragment = findViewById(R.id.btnDialogFragment);
 25        btnDialogFragmentFullScreen = findViewById(R.id.btnDialogFragmentFullScreen);
 26        btnAlertDialogFragment = findViewById(R.id.btnAlertDialogFragment);
 27
 28        btnEmbedDialogFragment.setOnClickListener(this);
 29        btnDialogFragment.setOnClickListener(this);
 30        btnDialogFragmentFullScreen.setOnClickListener(this);
 31        btnAlertDialogFragment.setOnClickListener(this);
 32
 33    }
 34
 35    @Override
 36    public void onClick(View view) {
 37
 38        switch (view.getId()) {
 39            case R.id.btnEmbedDialogFragment:
 40                MyDialogFragment dialogFragment = new MyDialogFragment();
 41
 42                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
 43
 44                ft.replace(R.id.frameLayout, dialogFragment);
 45                ft.commit();
 46                break;
 47
 48            case R.id.btnDialogFragment:
 49                dialogFragment = new MyDialogFragment();
 50
 51                Bundle bundle = new Bundle();
 52                bundle.putBoolean("notAlertDialog", true);
 53
 54                dialogFragment.setArguments(bundle);
 55
 56                ft = getSupportFragmentManager().beginTransaction();
 57                Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
 58                if (prev != null) {
 59                    ft.remove(prev);
 60                }
 61                ft.addToBackStack(null);
 62
 63                dialogFragment.show(ft, "dialog");
 64                break;
 65
 66            case R.id.btnDialogFragmentFullScreen:
 67                dialogFragment = new MyDialogFragment();
 68
 69                bundle = new Bundle();
 70                bundle.putString("email", "[email protected]");
 71                bundle.putBoolean("fullScreen", true);
 72                bundle.putBoolean("notAlertDialog", true);
 73
 74                dialogFragment.setArguments(bundle);
 75
 76                ft = getSupportFragmentManager().beginTransaction();
 77                prev = getSupportFragmentManager().findFragmentByTag("dialog");
 78                if (prev != null) {
 79                    ft.remove(prev);
 80                }
 81                ft.addToBackStack(null);
 82
 83                dialogFragment.show(ft, "dialog");
 84                break;
 85
 86            case R.id.btnAlertDialogFragment:
 87                dialogFragment = new MyDialogFragment();
 88
 89                ft = getSupportFragmentManager().beginTransaction();
 90                prev = getSupportFragmentManager().findFragmentByTag("dialog");
 91                if (prev != null) {
 92                    ft.remove(prev);
 93                }
 94                ft.addToBackStack(null);
 95
 96                dialogFragment.show(ft, "dialog");
 97                break;
 98        }
 99    }
100
101    @Override
102    public void onFinishEditDialog(String inputText) {
103
104        if (TextUtils.isEmpty(inputText)) {
105            textView.setText("Email was not entered");
106        } else
107            textView.setText("Email entered: " + inputText);
108    }
109}

上面的类实现了一个接口MyDialogFragment. DialogFragment,每当DialogFragment的按钮被单击时,它就会触发方法onDialogshEditDialog。它显示在活动对话框中输入的数据。下面给出了MyDialogFragment.java类的代码:

  1package com.journaldev.androiddialogfragment;
  2
  3import android.app.Dialog;
  4import android.content.DialogInterface;
  5import android.os.Bundle;
  6import android.support.annotation.NonNull;
  7import android.support.annotation.Nullable;
  8import android.support.v4.app.DialogFragment;
  9import android.support.v7.app.AlertDialog;
 10import android.text.TextUtils;
 11import android.util.Log;
 12import android.view.LayoutInflater;
 13import android.view.View;
 14import android.view.ViewGroup;
 15import android.widget.Button;
 16import android.widget.EditText;
 17
 18public class MyDialogFragment extends DialogFragment {
 19
 20    @NonNull
 21    @Override
 22    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
 23
 24        if (getArguments() != null) {
 25            if (getArguments().getBoolean("notAlertDialog")) {
 26                return super.onCreateDialog(savedInstanceState);
 27            }
 28        }
 29        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
 30        builder.setTitle("Alert Dialog");
 31        builder.setMessage("Alert Dialog inside DialogFragment");
 32
 33        builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
 34            @Override
 35            public void onClick(DialogInterface dialog, int which) {
 36                dismiss();
 37            }
 38        });
 39
 40        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
 41            @Override
 42            public void onClick(DialogInterface dialog, int which) {
 43                dismiss();
 44            }
 45        });
 46
 47        return builder.create();
 48
 49    }
 50
 51    @Nullable
 52    @Override
 53    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 54        return inflater.inflate(R.layout.fragment_sample_dialog, container, false);
 55
 56    }
 57
 58    @Override
 59    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
 60        super.onViewCreated(view, savedInstanceState);
 61
 62        final EditText editText = view.findViewById(R.id.inEmail);
 63
 64        if (getArguments() != null && !TextUtils.isEmpty(getArguments().getString("email")))
 65            editText.setText(getArguments().getString("email"));
 66
 67        Button btnDone = view.findViewById(R.id.btnDone);
 68        btnDone.setOnClickListener(new View.OnClickListener() {
 69            @Override
 70            public void onClick(View view) {
 71
 72                DialogListener dialogListener = (DialogListener) getActivity();
 73                dialogListener.onFinishEditDialog(editText.getText().toString());
 74                dismiss();
 75            }
 76        });
 77    }
 78
 79    @Override
 80    public void onResume() {
 81        super.onResume();
 82
 83    }
 84
 85    @Override
 86    public void onCreate(@Nullable Bundle savedInstanceState) {
 87        super.onCreate(savedInstanceState);
 88
 89        Log.d("API123", "onCreate");
 90
 91        boolean setFullScreen = false;
 92        if (getArguments() != null) {
 93            setFullScreen = getArguments().getBoolean("fullScreen");
 94        }
 95
 96        if (setFullScreen)
 97            setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
 98    }
 99
100    @Override
101    public void onDestroyView() {
102        super.onDestroyView();
103    }
104
105    public interface DialogListener {
106        void onFinishEditDialog(String inputText);
107    }
108
109}

onsightDialog中,我们创建一个普通的AlertDialog。dismiss()函数关闭对话框。下面给出了上述应用程序的输出:android dialogfragment output请注意,在全屏对话框中,输入字段的数据已经传递。本教程到此结束。您可以从下面的链接下载该项目:

AndroidDialogFragment

Github项目链接

Published At
Categories with 技术
Tagged with
comments powered by Disqus