121

通常のダイアログを表示する必要があるフラグメントがいくつかあります。これらのダイアログで、ユーザーははい/いいえの回答を選択でき、フラグメントはそれに応じて動作する必要があります。

現在、FragmentクラスにはonCreateDialog()オーバーライドするメソッドがないため、ダイアログを外側の .xml に実装する必要があると思いますActivity。それは問題ありませんActivityが、選択した回答を何らかの方法でフラグメントに報告する必要があります。もちろん、ここでコールバック パターンを使用することもできます。そのため、フラグメントは自身をActivityリスナー クラスに登録し、アクティビティはそれを介して応答を返すか、またはそのようなものになります。

しかし、これは、フラグメントに「単純な」はい/いいえダイアログを表示するという単純なタスクにとっては、かなり混乱しているようです。また、この方法でFragmentは自己完結型ではなくなります。

これを行うためのよりクリーンな方法はありますか?

編集:

この質問に対する答えは、DialogFragments を使用して Fragments からダイアログを表示する方法を詳しく説明していません。知る限り、行く方法は次のとおりです。

  1. フラグメントを表示します。
  2. 必要に応じて、DialogFragment をインスタンス化します。
  3. を使用して、元の Fragment をこの DialogFragment のターゲットとして設定し.setTargetFragment()ます。
  4. 元の Fragment から .show() を使用して DialogFragment を表示します。
  5. ユーザーがこの DialogFragment で何らかのオプションを選択すると、この選択について元の Fragment に通知されます (たとえば、ユーザーが「はい」をクリックした場合)。元の Fragment の参照を .getTarget() で取得できます。
  6. DialogFragment を破棄します。
4

7 に答える 7

39

DialogFragment を使用することが最善の選択肢であるという以前に受け入れられた答えを慎重に疑う必要があります。DialogFragment の意図された (主な) 目的は、ダイアログ自体であるフラグメントを表示することであり、表示するダイアログがあるフラグメントを表示することではないようです

フラグメントのアクティビティを使用して、ダイアログとフラグメントの間を仲介することが望ましいオプションだと思います。

于 2011-03-28T17:52:07.340 に答える
37

代わりにDialogFragmentを使用する必要があります。

于 2011-03-23T01:25:18.510 に答える
25

yes/no DialogFragment の完全な例を次に示します。

クラス:

public class SomeDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setMessage("Sure you wanna do this!")
            .setNegativeButton(android.R.string.no, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing (will close dialog)
                }
            })
            .setPositiveButton(android.R.string.yes,  new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do something
                }
            })
            .create();
    }
}

ダイアログを開始するには:

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        // Create and show the dialog.
        SomeDialog newFragment = new SomeDialog ();
        newFragment.show(ft, "dialog");

クラスに onClickListener を実装させ、埋め込みリスナーの代わりにそれを使用することもできます。

アクティビティへのコールバック

コールバックを実装したい場合、これはあなたのアクティビティで行われる方法です:

YourActivity extends Activity implements OnFragmentClickListener

@Override
public void onFragmentClick(int action, Object object) {
    switch(action) {
        case SOME_ACTION:
        //Do your action here
        break;
    }
}

コールバック クラス:

public interface OnFragmentClickListener {
    public void onFragmentClick(int action, Object object);
}

次に、フラグメントからコールバックを実行するには、リスナーが次のようにアタッチされていることを確認する必要があります。

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentClickListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement listeners!");
    }
}

コールバックは次のように実行されます。

mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter.
于 2013-04-23T17:13:00.770 に答える
13

私にとって、それは次のことでした-

マイフラグメント:

public class MyFragment extends Fragment implements MyDialog.Callback
{
    ShowDialog activity_showDialog;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            activity_showDialog = (ShowDialog)activity;
        }
        catch(ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "ShowDialog interface needs to be     implemented by Activity.", e);
            throw e;
        }
    }

    @Override
    public void onClick(View view) 
    {
        ...
        MyDialog dialog = new MyDialog();
        dialog.setTargetFragment(this, 1); //request code
        activity_showDialog.showDialog(dialog);
        ...
    }

    @Override
    public void accept()
    {
        //accept
    }

    @Override
    public void decline()
    {
        //decline
    }

    @Override
    public void cancel()
    {
        //cancel
    }

}

マイダイアログ:

public class MyDialog extends DialogFragment implements View.OnClickListener
{
    private EditText mEditText;
    private Button acceptButton;
    private Button rejectButton;
    private Button cancelButton;

    public static interface Callback
    {
        public void accept();
        public void decline();
        public void cancel();
    }

    public MyDialog()
    {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.dialogfragment, container);
        acceptButton = (Button) view.findViewById(R.id.dialogfragment_acceptbtn);
        rejectButton = (Button) view.findViewById(R.id.dialogfragment_rejectbtn);
        cancelButton = (Button) view.findViewById(R.id.dialogfragment_cancelbtn);
        acceptButton.setOnClickListener(this);
        rejectButton.setOnClickListener(this);
        cancelButton.setOnClickListener(this);
        getDialog().setTitle(R.string.dialog_title);
        return view;
    }

    @Override
    public void onClick(View v)
    {
        Callback callback = null;
        try
        {
            callback = (Callback) getTargetFragment();
        }
        catch (ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "Callback of this class must be implemented by target fragment!", e);
            throw e;
        }

        if (callback != null)
        {
            if (v == acceptButton)
            {   
                callback.accept();
                this.dismiss();
            }
            else if (v == rejectButton)
            {
                callback.decline();
                this.dismiss();
            }
            else if (v == cancelButton)
            {
                callback.cancel();
                this.dismiss();
            }
        }
    }
}

アクティビティ:

public class MyActivity extends ActionBarActivity implements ShowDialog
{
    ..

    @Override
    public void showDialog(DialogFragment dialogFragment)
    {
        FragmentManager fragmentManager = getSupportFragmentManager();
        dialogFragment.show(fragmentManager, "dialog");
    }
}

DialogFragment レイアウト:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/dialogfragment_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:text="@string/example"/>

    <Button
        android:id="@+id/dialogfragment_acceptbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/dialogfragment_textview"
        android:text="@string/accept"
        />

    <Button
        android:id="@+id/dialogfragment_rejectbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_alignLeft="@+id/dialogfragment_acceptbtn"
        android:layout_below="@+id/dialogfragment_acceptbtn"
        android:text="@string/decline" />

     <Button
        android:id="@+id/dialogfragment_cancelbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_rejectbtn"
        android:layout_below="@+id/dialogfragment_rejectbtn"
        android:text="@string/cancel" />

     <Button
        android:id="@+id/dialogfragment_heightfixhiddenbtn"
        android:layout_width="200dp"
        android:layout_height="20dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_cancelbtn"
        android:layout_below="@+id/dialogfragment_cancelbtn"
        android:background="@android:color/transparent"
        android:enabled="false"
        android:text=" " />
</RelativeLayout>

名前dialogfragment_heightfixhiddenbtnが示すように、下のボタンの高さが半分にカットされているのを修正する方法がわかりませんでしたwrap_content。ハックしてごめんなさい。

于 2014-07-31T10:06:19.307 に答える