7

コンポーネント上でポップアップDialogFragmentをクリックするフラグメントがあります。このダイアログフラグメントには、オプションのリストが含まれています。リストのオプションが選択されたら、フィールド更新手順を実行できるようにフラグメントに通知したいと思います。私はこのようなことをしました

@Override
public void onClick(DialogInterface dialog, int item) {
     updateSharedPreference(item);
     Log.e("ProfilePersonaListDialog", "Click on dialog, inside onClick");
     OnCloseListDialogListener act = (OnCloseListDialogListener) getActivity();
     act.onDialogListSelection();

     dismiss();
}

ただし、このgetActivity()は、ダイアログフラグメントをトリガーしたフラグメントではなく、FragmentActivityを呼び出します。現在開いている/実行中のフラグメントを強制終了し、更新されたフィールドを取得する新しいインスタンスを呼び出すことはできますが、それは避けたい汚い解決策です。

ダイアログフラグメントでオプションを選択したら、フラグメントのこの更新をどのように行うかについての提案はありますか?

4

3 に答える 3

7

ただ解決策を持って戻ってきます。私の問題は、実際には、DialogFragmentのshow()のパラメーターとして現在のフラグメントgetTag()文字列を転送することでした。ここに興味のある人がサンプルを作業している場合。

シンプルなリスナーを作成する

public interface OnCloseListDialogListener {
    public void onDialogListSelection();
}

DialogFragmentを拡張する新しいダイアログを作成します



public class ListDialogFragment extends DialogFragment implements DialogInterface.OnClickListener {

    private PersonaData[] mPersonaData;
    private String[] mPersonaName;
    private final String TAG;

    public static ListDialogFragment newInstance(PersonaData[] personaData, String tag) {
        ListDialogFragment dialog = new ListDialogFragment(personaData, tag);
        Bundle bundle = new Bundle();
        dialog.setArguments(bundle);
        return dialog;
    }

    private ListDialogFragment(PersonaData[] personaData, String tag) {
        this.mPersonaData = personaData.clone();
        this.TAG = tag;
    }

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setCancelable(true);
        int style = DialogFragment.STYLE_NORMAL, theme = 0;
        setStyle(style, theme);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(R.string.dialog_title);
        mPersonaName = getData();//Your own implementation here
        builder.setNegativeButton("Cancel", this);
        builder.setSingleChoiceItems(mPersonaName, -1, new SingleChoiceListener());
        return builder.create();

    }

    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
    }

    private class SingleChoiceListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            updateSharedPreference(item);
            OnCloseListDialogListener act = (OnCloseListDialogListener) getFragmentManager().findFragmentByTag(TAG);
            act.onDialogListSelection();
            dismiss();
        }
    }
}

そして、このダイアログを呼び出したいフラグメントで、以下のようにします。DIALOGは文字列定数です私はそこにダイアログだけを置きました


SOME_CLICKABLE.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        FragmentManager manager = getFragmentManager();
        ListDialogFragment dialog = ListDialogFragment.newInstance(mPersona, getTag());
        dialog.show(manager, DIALOG);
    }
});
于 2012-06-18T08:24:04.087 に答える
6

ほとんどの場合、何らかの説明Fragmentのコンテキストで実行されておりActivity、子フラグメントが親アクティビティによって暗黙的に実装されたインターフェイスでメソッドを呼び出すことができることに注意する必要があります(コードのキャストで示されています)。スニペット)。Tomaszが指摘するように参照を機能させると、あなたは金色になります。

ただし、:)ダイアログフラグメントの再利用を支援するために、を活用することをお勧めしますBroadcastReceiverBroadcastReceiverは、 「x」を実行したというメッセージをブロードキャストするだけです。親アクティビティまたは実際に他のトップレベルコンポーネントは、「x」をリッスンしていると宣言できます。ダイアログコンポーネントでイベントが発生すると、このイベントは親アクティビティによって収集され、onReceiveフィールドを更新するために必要なコードを実行できます。

個人的なレベルでは、各フラグメントの目的を考えてモジュール化する必要があるため、キャスティングインターフェイスアプローチよりもこの緩い結合を好みます。

試してみたい場合は、BroadcastReceiversの開発ガイドセクションを読んで、次の手順に従ってください。

  1. BroadcastReceiver親アクティビティにを実装します。onReceiveメソッドを実装する必要があることに注意してください。

  2. 親アクティビティのonResumeメソッドをオーバーライドし、インテントアクション「blah」を使用してアクティビティをイベントの受信者として登録します。何かのようなもの;

     @Override
     protected void onResume() {
     super.onResume();
     registerReceiver(this, new IntentFilter("blah"));
    }
    
  3. 親アクティビティのonPauseメソッドをオーバーライドし、アクティビティをレシーバーとして登録解除して、「リークされたレシーバー」を回避します(後でわかります)。

    @Override
    protected void onPause() {
     super.onPause();
     unregisterReceiver(deleteSpotReceiver);
    }
    
  4. あなたのDialogFragment onClick火の中であなたの親の活動が「聞いている」イベント。

    @Override
    public void onClick(DialogInterface dialog, int item) {
        updateSharedPreference(item);
        Log.e("ProfilePersonaListDialog", "Click on dialog, inside onClick");
        final Intent intent = new Intent();
        intent.setAction("blah");
        getActivity().sendBroadcast(intent);
        dismiss();
    }
    

親アクティビティがメッセージを収集し、処理を続行できます。その方法を採用することにした場合はお知らせください。

于 2012-05-15T20:08:46.603 に答える
1

あなたが上でそれをしたのと同じように、あなたの活動にそのようなsthを追加してください:

public void onDialogListSelection() {
    AnotherFragment anotherFragment = (AnotherFragment) getSupportFragmentManager()
            .findFragmentById(R.id.anotherFragment);
    anotherFragment.customMethodToNotifyListHasBeenSelected();
}

もちろん、サポートライブラリを使用していない場合は、getFragmentManagerの代わりにを呼び出してgetSupportFragmentManagerください。

于 2012-05-08T17:51:53.833 に答える