アンドロイドのダイアログフラグメント

このチュートリアルでは、DialogFragmentとは何かについて説明します。また、シンプルなAndroidアプリケーションを使って、DialogFragmentsとDialogsの違いも確認します。

アンドロイドのダイアログフラグメント

DialogFragmentは、Fragmentクラスを拡張したユーティリティクラスです。これはv4サポートライブラリの一部であり、アクティビティ内に浮かび上がるオーバーレイモーダルウィンドウを表示するために使用されます。基本的に、DialogFragmentはFragment内でDialogを表示します。

Googleは、アクティビティでシンプルなアラートダイアログビルダーの代わりにDialogFragmentを使用することを推奨しています。

なぜですか?

  • DialogFragments have their own lifecycle methods. So the Activity is free from the responsibility of telling the Dialog what to do.
  • No more IllegalStateExceptions and leaked window crashes. This was pretty common when the activity was destroyed with the Alert Dialog still there.

DialogFragmentはフラグメントであるため、アクティビティのライフサイクルに統合され、ダイアログウィンドウ内で行われる操作が一貫性を持つことを保証します。Androidアプリケーションでダイアログを作成する際には、DialogFragmentを使用することが良いプラクティスです。クラスはDialogFragmentを拡張する必要があり、onCreateDialogと/またはonCreateViewを実装する必要があります。DialogFragmentを使用してダイアログを作成する方法は2つあります。

  • onCreateDialog – Here you can create the AlertDialog using the AlertDialog.Builder class.
  • onCreateView – Here you can create a Dialog using a custom view defined.

ダイアログを表示するために、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");

show()の第2引数には任意のタグを設定することができます。ダイアログをフラグメントに埋め込むために、通常のフラグメントのようにFramelayoutにそのフラグメントを追加するだけで作成できます。

知っていますか?ダイアログだけでなく、フラグメントでもカスタムビューを表示することができます。

DialogFragmentクラスがインスタンス化されると、以下の順序でメソッドが呼び出されます。

  • onCreate
  • onCreateDialog
  • onCreateView
  • onViewCreated
  • onDestroy

ダイアログフラグメントにデータを渡す方法とデータを返す方法

データをDialogFragmentクラスに渡すためには、クラスのインスタンスを使用してsetArgumentsでデータを設定するだけです。DialogFragmentからデータをアクティビティ/他のフラグメントに戻すためには、カスタムインターフェースを作成する必要があります。以下のセクションでは、次のことを行うAndroidアプリケーションを作成します。

  • Creates a Simple DialogFragment Dialog
  • A DialogFragment embedded in the Activity
  • DialogFragment with a style.
  • DialogFragment that returns data

プロジェクトの構造

コード

以下に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>

各ボタンは異なるタイプのDialogFragmentを開始します。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>

私たちのダイアログは基本的なログインフォームを表示します。MainActivity.javaのコードは以下の通りです:

package com.scdev.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);
    }
}

上記のクラスは、ボタンがクリックされるたびにメソッドonFinishEditDialogをトリガーするMyDialogFragment.DialogListenerインターフェースを実装しています。ダイアログで入力されたデータをアクティビティ上に表示します。MyDialogFragment.javaクラスのコードは以下の通りです。

package com.scdev.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);
    }


}

onCreateDialog内で通常のAlertDialogを作成します。dismiss()関数はダイアログを閉じます。上記のアプリケーションの実行結果は以下の通りです:全画面のダイアログでは、入力フィールドのデータがすでに渡されていることに注意してください。これでチュートリアルは終了です。プロジェクトは以下のリンクからダウンロードできます。

アンドロイドダイアログフラグメント

「GitHubのプロジェクトリンク」

コメントを残す 0

Your email address will not be published. Required fields are marked *


广告
広告は10秒後に閉じます。
bannerAds