Hướng dẫn sử dụng Android DialogFragment

1- Android DialogFragment

Android DialogFragment là một fragment chứa một Dialog (hộp thoại), nó điều khiển sự hoạt động của Dialog, chẳng hạn quyết định khi nào cần ẩn, hiển thị, hoặc loại bỏ (dismiss) Dialog này. Bạn nên tương tác với Dialog thông qua các phương thức của DialogFragment thay vì trực tiếp.
Có thể bạn sẽ đặt ra câu hỏi: "Tại sao chúng tại lại cần DialogFragment trong khi chúng ta đã có Dialog?". Câu trả lời là DialogFragment được tạo ra để khắc phục một số điểm yếu của Dialog.
  • CẦN CHÉM GIÓ THÊM Ở ĐÂY!

Xem thêm:
Rất dễ dàng để bạn có được một DialogFragment, chỉ cần 2 bước sau:
Viết một lớp YourDialogFragment mở rộng từ lớp DialogFragment. Ghi đè (override) phương thức onCreateDialog(Bundle), phương thức này trả về một Dialog của bạn ( YourDialog). Như vậy YourDialogFragment đóng vai trò là một bộ chứa của YourDialog.
Android DialogFragment Javadocs:

2- Ví dụ DialogFragment

Trong ví dụ này chúng ta sẽ tạo lớp YesNoDialogFragment mở rộng từ lớp DialogFragment. Lớp này chứa một đối tượng AlertDialog với 2 button: YES/NO.
Ví dụ này sẽ chỉ cho bạn làm sao để tạo và hiển thị YesNoDialogFragment từ một Activity. Bạn cũng có thể tạo và hiển thị YesNoDialogFragment từ một Fragment khác với một chút thay đổi về code.
OK, Trên Android Studio tạo mới một project:
  • File > New > New Project > Empty Activity
    • Name: DialogFragmentExample
    • Package name: org.o7planning.dialogfragmentexample
    • Language: Java
Giao diện của ứng dụng:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Show Dialog Fragment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:gravity="center"
        android:text="---"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button_show" />
</androidx.constraintlayout.widget.ConstraintLayout>
YesNoDialogFragment.java
package org.o7planning.dialogfragmentexample;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;

public class YesNoDialogFragment extends DialogFragment {

    public static final String ARG_TITLE = "YesNoDialog.Title";
    public static final String ARG_MESSAGE = "YesNoDialog.Message";

    private YesNoDialogFragmentListener listener;

    public interface YesNoDialogFragmentListener {
        /**
         *
         * @param resultCode - Activity.RESULT_OK, Activity.RESULT_CANCEL
         * @param data
         */
         public void onYesNoResultDialog(int resultCode, @Nullable Intent data);
    }

    public YesNoDialogFragment() {

    }

    public void setOnYesNoDialogFragmentListener(YesNoDialogFragmentListener listener) {
        this.listener = listener;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Bundle args = getArguments();
        String title = args.getString(ARG_TITLE);
        String message = args.getString(ARG_MESSAGE);

        return new AlertDialog.Builder(getActivity())
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        buttonOkClick();
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        buttonNoClick();
                    }
                })
                .create();
    }

    private void buttonOkClick() {
        int resultCode = Activity.RESULT_OK;

        Bundle bundle = new Bundle();
        bundle.putString("key1", "Value 1");
        bundle.putString("key2", "Value 2");
        Intent data  = new Intent().putExtras(bundle);

        // Open this DialogFragment from an Activity.
        if(this.listener != null)  {
            this.listener.onYesNoResultDialog(Activity.RESULT_OK, data);
        }
        // Open this DialogFragment from another Fragment.
        else {
            // Send result to your TargetFragment.
            // See (Your) TargetFragment.onActivityResult()
            getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, data);
        }
    }

    private void buttonNoClick() {
        int resultCode = Activity.RESULT_CANCELED;
        Intent data  = null;

         // Open this DialogFragment from an Activity.
        if(this.listener != null)  {
            this.listener.onYesNoResultDialog(resultCode, data);
        }
        // Open this DialogFragment from another Fragment.
        else {
            // Send result to your TargetFragment.
            // See (Your) TargetFragment.onActivityResult()
            getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, data);
        }
    }

}
MainActivity.java
package org.o7planning.dialogfragmentexample;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity
        implements YesNoDialogFragment.YesNoDialogFragmentListener {

    private Button buttonShow;
    private TextView textView;

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

        this.buttonShow = (Button) this.findViewById(R.id.button_show);
        this.textView = (TextView) this.findViewById(R.id.textView);

        this.buttonShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buttonShowClicked();
            }
        });
    }

    // User click on "Show Dialog" button.
    private void buttonShowClicked()  {
        this.textView.setText("---");

        // Create YesNoDialogFragment
        DialogFragment dialogFragment = new YesNoDialogFragment();

        // Arguments:
        Bundle args = new Bundle();
        args.putString(YesNoDialogFragment.ARG_TITLE, "Confirmation");
        args.putString(YesNoDialogFragment.ARG_MESSAGE, "Do you like this example?");
        dialogFragment.setArguments(args);

        FragmentManager fragmentManager = this.getSupportFragmentManager();

        // Show:
        dialogFragment.show(fragmentManager, "Dialog");
    }

    @Override
    public void onAttachFragment(Fragment fragment) {
        if (fragment instanceof YesNoDialogFragment) {
            YesNoDialogFragment yesNoDialogFragment = (YesNoDialogFragment) fragment;
            yesNoDialogFragment.setOnYesNoDialogFragmentListener(this);
        }
    }

    // Implement method of YesNoDialogFragment.YesNoDialogFragmentListener
    @Override
    public void onYesNoResultDialog(int resultCode, @Nullable Intent data) {
        if(resultCode == Activity.RESULT_OK) {
            String value1 = data.getStringExtra("key1"); // ...
            this.textView.setText("You select YES");
        } else if(resultCode == Activity.RESULT_CANCELED) {
            this.textView.setText("You select NO");
        } else {
            this.textView.setText("You don't select");
        }
    }

}
Dưới đây là code để tạo và hiển thị YesNoDialogFragment từ một Fragment khác.
ExampleFragment.java
package org.o7planning.dialogfragmentexample;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class ExampleFragment extends Fragment {

    private static final int REQUEST_CODE_YESNO_DIALOG_FRAGMENT = 1000;
    
    public ExampleFragment() {
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_example, container, false);
    }

    // Call this method to show YesNoDialogFragment
    private void showYesNoDialogFragment() {
        // Create YesNoDialogFragment
        DialogFragment dialogFragment = new YesNoDialogFragment();

        // Arguments:
        Bundle args = new Bundle();
        args.putString(YesNoDialogFragment.ARG_TITLE, "Confirmation");
        args.putString(YesNoDialogFragment.ARG_MESSAGE, "Do you like this example?");
        dialogFragment.setArguments(args);

        // YesNoDialogFragment will return results for targetFragment.
        // So, Need to Override onActivityResult() method, to get results.
        Fragment targetFragment = this;

        // IMPORTANT!!
        dialogFragment.setTargetFragment(targetFragment, REQUEST_CODE_YESNO_DIALOG_FRAGMENT);

        FragmentManager fragmentManager = this.getFragmentManager();
        // Show:
        dialogFragment.show(fragmentManager, "Dialog");
    }

    // Results are returned by YesNoDialogFragment.
    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == REQUEST_CODE_YESNO_DIALOG_FRAGMENT) {
            if(resultCode == Activity.RESULT_OK) {
                Toast.makeText(this.getContext(), "You select YES", Toast.LENGTH_LONG).show();
            } else if(resultCode == Activity.RESULT_CANCELED) {
                Toast.makeText(this.getContext(), "You select NO", Toast.LENGTH_LONG).show();
            }
        }
    }
}

Xem thêm các chuyên mục: