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内。
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一样 。
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