Android DialogFragment

In this tutorial, we’ll be discussing what are DialogFragments. We’ll see how they are different from the Dialogs too with the help of a simple android application.

在本教程中,我们将讨论什么是DialogFragments。 我们将在一个简单的android应用程序的帮助下,了解它们与对话框的不同之处。

Android DialogFragments (Android DialogFragments)

DialogFragment is a utility class which extends the Fragment class. It is a part of the v4 support library and is used to display an overlay modal window within an activity that floats on top of the rest of the content.

DialogFragment是一个实用程序类,它扩展了Fragment类。 它是v4支持库的一部分,用于显示浮动在内容其余部分顶部的活动中的覆盖模式窗口。

Essentially a DialogFragment displays a Dialog but inside a Fragment.

本质上,DialogFragment显示一个Dialog,但在Fragment内。

Google recommends that we use DialogFragment instead of a simple Alert Dialog builder in the activity.
Google建议我们在活动中使用DialogFragment而不是简单的Alert Dialog构建器。

Why so?

为什么这样?

  • DialogFragments have their own lifecycle methods. So the Activity is free from the responsibility of telling the Dialog what to do.

    DialogFragments有其自己的生命周期方法。 因此,活动无需承担告诉对话框该做什么的责任。
  • No more IllegalStateExceptions and leaked window crashes. This was pretty common when the activity was destroyed with the Alert Dialog still there.

    没有更多的IllegalStateExceptions和泄漏的窗口崩溃。 当活动仍在“警报对话框”中被销毁时,这很常见。

Because DialogFragment is a fragment, it integrates into the activity’s lifecycle and ensures that what’s happening in the dialog window remains consistent. It’s a good practice to use DialogFragments to create dialogs in your android application.

因为DialogFragment是一个片段,所以它集成到活动的生命周期中,并确保对话框窗口中发生的事情保持一致。 使用DialogFragments在Android应用程序中创建对话框是一个好习惯。

Your class must extend DialogFragment with at least onCreateDialog and/or onCreateView implemented.

您的类必须扩展DialogFragment,至少应实现onCreateDialog和/或onCreateView

You can create Dialogs using DialogFragment in two ways:

您可以通过以下两种方式使用DialogFragment创建对话框:

  • onCreateDialog – Here you can create the AlertDialog using the AlertDialog.Builder class.

    onCreateDialog –在这里,您可以使用AlertDialog.Builder类创建AlertDialog。
  • onCreateView – Here you can create a Dialog using a custom view defined.

    onCreateView –在这里您可以使用定义的自定义视图创建一个Dialog。

In order to create a DialogFragment that shows a Dialog, we need to call the method show() on the DialogFragment instance as:

为了创建一个显示Dialog的DialogFragment,我们需要在DialogFragment实例上调用show()方法为:

MyDialogFragment dialogFragment = new MyDialogFragment();
FragmentTranscation ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
   ft.remove(prev);
}
ft.addToBackStack(null);
dialogFragment.show(ft, "dialog");

We can set any tag as the second argument of show().

我们可以将任何标签设置为show()的第二个参数。

In order to create a DialogFragment that embeds the dialog in a fragment, we just add the Fragment to the Framelayout as we do it with any Fragment.

为了创建一个将对话框嵌入片段中的DialogFragment,我们只需add Fragment add到Framelayout中,就如同使用任何Fragment一样

Do you know? 你知道吗?

You can show the custom views in Fragments as well instead of just Dialogs.

您也可以在“片段”中显示自定义视图,而不仅仅是“对话框”。

When a DialogFragment class is instantiated. Methods are called in the following order:

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

  • onCreate

    onCreate
  • onCreateDialog

    onCreateDialog
  • onCreateView

    onCreateView
  • onViewCreated

    onViewCreated
  • onDestroy

    onDestroy

与DialogFragment进行数据传递 (Passing Data to and From the DialogFragment)

In order to pass the data to the DialogFragment class, we can simply set the data using setArguments on the instance of the class.

为了将数据传递给DialogFragment类,我们可以简单地使用该类实例上的setArguments设置数据。

In order to return the data from the DialogFragments to the Activity/another fragment, we need to create our custom interface.

为了将数据从DialogFragments返回到Activity /另一个片段,我们需要创建自定义接口。

In the following section, we’ll be creating an android application that does the following things:

在以下部分中,我们将创建一个执行以下操作的android应用程序:

  • Creates a Simple DialogFragment Dialog

    创建一个简单的DialogFragment对话框
  • A DialogFragment embedded in the Activity

    嵌入在Activity中的DialogFragment
  • DialogFragment with a style.

    带有样式的DialogFragment。
  • DialogFragment that returns data

    返回数据的DialogFragment

项目结构 (Project Structure)

(Code)

The code for the activity_main.xml class is given below:

下面给出了activity_main.xml类的代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/btnEmbedDialogFragment"
        android:layout_alignParentTop="true" />


    <Button
        android:id="@+id/btnEmbedDialogFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_above="@+id/btnDialogFragment"
        android:text="EMBED DIALOG FRAGMENT" />

    <Button
        android:id="@+id/btnDialogFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginTop="8dp"
        android:text="SIMPLE DIALOG FRAGMENT" />


    <Button
        android:id="@+id/btnDialogFragmentFullScreen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnDialogFragment"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="DIALOG FRAGMENT FULL SCREEN" />


    <Button
        android:id="@+id/btnAlertDialogFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnDialogFragmentFullScreen"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="Alert Dialog Fragment" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnAlertDialogFragment"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

Each of the Buttons would start a different type of DialogFragment.

每个按钮将启动不同类型的DialogFragment。

The xml layout for the custom view for a DialogFragment is defined in fragment_sample_dialog.xml file as shown below:

DialogFragment的自定义视图的xml布局在fragment_sample_dialog.xml文件中定义,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">


    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Please enter your username and password" />


    <EditText
        android:id="@+id/inEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Email Address"
        android:inputType="textEmailAddress" />

    <EditText
        android:id="@+id/inPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Password"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/btnDone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Done" />
</LinearLayout>

So our Dialog would show a basic Login form.

因此,我们的对话框将显示一个基本的登录表单。

The code for the MainActivity.java is given below:

MainActivity.java的代码如下:

package com.journaldev.androiddialogfragment;


import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, MyDialogFragment.DialogListener {

    Button btnEmbedDialogFragment, btnDialogFragment, btnDialogFragmentFullScreen, btnAlertDialogFragment;
    TextView textView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        textView = findViewById(R.id.textView);
        btnEmbedDialogFragment = findViewById(R.id.btnEmbedDialogFragment);
        btnDialogFragment = findViewById(R.id.btnDialogFragment);
        btnDialogFragmentFullScreen = findViewById(R.id.btnDialogFragmentFullScreen);
        btnAlertDialogFragment = findViewById(R.id.btnAlertDialogFragment);

        btnEmbedDialogFragment.setOnClickListener(this);
        btnDialogFragment.setOnClickListener(this);
        btnDialogFragmentFullScreen.setOnClickListener(this);
        btnAlertDialogFragment.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {

        switch (view.getId()) {
            case R.id.btnEmbedDialogFragment:
                MyDialogFragment dialogFragment = new MyDialogFragment();

                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

                ft.replace(R.id.frameLayout, dialogFragment);
                ft.commit();
                break;

            case R.id.btnDialogFragment:
                dialogFragment = new MyDialogFragment();

                Bundle bundle = new Bundle();
                bundle.putBoolean("notAlertDialog", true);

                dialogFragment.setArguments(bundle);

                ft = getSupportFragmentManager().beginTransaction();
                Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);


                dialogFragment.show(ft, "dialog");
                break;

            case R.id.btnDialogFragmentFullScreen:
                dialogFragment = new MyDialogFragment();

                bundle = new Bundle();
                bundle.putString("email", "xyz@gmail.com");
                bundle.putBoolean("fullScreen", true);
                bundle.putBoolean("notAlertDialog", true);

                dialogFragment.setArguments(bundle);


                ft = getSupportFragmentManager().beginTransaction();
                prev = getSupportFragmentManager().findFragmentByTag("dialog");
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);


                dialogFragment.show(ft, "dialog");
                break;

            case R.id.btnAlertDialogFragment:
                dialogFragment = new MyDialogFragment();


                ft = getSupportFragmentManager().beginTransaction();
                prev = getSupportFragmentManager().findFragmentByTag("dialog");
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);


                dialogFragment.show(ft, "dialog");
                break;
        }
    }

    @Override
    public void onFinishEditDialog(String inputText) {

        if (TextUtils.isEmpty(inputText)) {
            textView.setText("Email was not entered");
        } else
            textView.setText("Email entered: " + inputText);
    }
}

The above class implements an interface MyDialogFragment.DialogListener which triggers the method onFinishEditDialog whenever the button of the DialogFragment is clicked.
It displays the data entered in the Dialog on the Activity.

上面的类实现了一个MyDialogFragment.DialogListener接口,只要单击onFinishEditDialog的按钮,该接口就会触发onFinishEditDialog方法。
它显示在“活动”对话框中输入的数据。

The code for the MyDialogFragment.java class is given below:

MyDialogFragment.java类的代码如下:

package com.journaldev.androiddialogfragment;

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class MyDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {


        if (getArguments() != null) {
            if (getArguments().getBoolean("notAlertDialog")) {
                return super.onCreateDialog(savedInstanceState);
            }
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Alert Dialog");
        builder.setMessage("Alert Dialog inside DialogFragment");

        builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dismiss();
            }
        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dismiss();
            }
        });

        return builder.create();

    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_sample_dialog, container, false);

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);


        final EditText editText = view.findViewById(R.id.inEmail);

        if (getArguments() != null && !TextUtils.isEmpty(getArguments().getString("email")))
            editText.setText(getArguments().getString("email"));

        Button btnDone = view.findViewById(R.id.btnDone);
        btnDone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                DialogListener dialogListener = (DialogListener) getActivity();
                dialogListener.onFinishEditDialog(editText.getText().toString());
                dismiss();
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();

    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d("API123", "onCreate");

        boolean setFullScreen = false;
        if (getArguments() != null) {
            setFullScreen = getArguments().getBoolean("fullScreen");
        }

        if (setFullScreen)
            setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    public interface DialogListener {
        void onFinishEditDialog(String inputText);
    }


}

Inside onCreateDialog we create a normal AlertDialog.
dismiss() function closes the Dialog.

onCreateDialog我们创建一个普通的AlertDialog。
dismiss()函数关闭对话框。

The output of the above application in action is given below:

上面应用程序的输出如下:

Notice that in the full screen Dialog, the data for the input field was already passed.

注意,在全屏对话框中,输入字段的数据已经传递。

That brings an end to this tutorial. You can download the project from the link below:

这样就结束了本教程。 您可以从下面的链接下载项目:

翻译自: https://www.journaldev.com/23096/android-dialogfragment

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值