7

我有片段,在组件上单击弹出窗口 DialogFragment。此对话框片段包含选项列表。When an option from list is selected I want to notify fragment so I can run fields update procedure. 我做了这样的事情

@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

只是带着解决方案回来。我的问题实际上是将当前片段 getTag() 字符串作为 DialogFragment 的 show() 参数转发。如果有人对这里感兴趣是工作样本。

创建简单的监听器

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某种描述的上下文下运行的,并且子 Fragment 可以在父 Activity 隐式实现的接口上调用方法(如代码中的强制转换所示)片段)。当你得到你的推荐信时,Tomasz 指出你会很成功。

但是,:) 为了帮助对话片段的可重用性,我建议您利用BroadcastReceivers. BroadcastReceiver 只是广播一条消息说我做了 'x'。然后,父活动或任何其他顶级组件可以声明我正在监听 'x'。一旦在对话框组件中触发了该事件,该事件将由父 Activity 收集onReceive,您可以在其中运行必要的代码来更新您的字段。

在个人层面上,我更喜欢这种松散耦合而不是强制转换接口方法,因为它迫使我思考每个 Fragment 的用途并使其保持模块化。

如果您想试一试,请阅读广播接收器上的开发指南部分并按照以下步骤操作;

  1. BroadcastReceiver在您的父活动中实施。onReceive请注意,需要实现一个方法。

  2. 覆盖父 Activity 的onResume方法并将 Activity 注册为具有意图操作“blah”的事件的接收者。就像是;

     @Override
     protected void onResume() {
     super.onResume();
     registerReceiver(this, new IntentFilter("blah"));
    }
    
  3. 覆盖父 Activity 的onPause方法,将 Activity 取消注册为接收器,以避免“泄漏的接收器”(你会发现)。

    @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

就像你在上面做的那样,在你的活动中添加这样的东西:

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

当然,如果您不使用支持库,请调用getFragmentManager而不是getSupportFragmentManager.

于 2012-05-08T17:51:53.833 回答