【问题标题】:How do I communicate between ListFragment and DialogFragment where the DialogFragment is invoked via the options menu of list fragment?如何在通过列表片段的选项菜单调用 DialogFragment 的 ListFragment 和 DialogFragment 之间进行通信?
【发布时间】:2014-10-09 09:08:37
【问题描述】:

我有一个实现 ListFragment 的类“ListFrag”,在该类中,我有一个嵌套的静态 DialogFragment 类“SortDialogFragment”,它通过选项菜单中的选项之一调用。该对话框的目的是为用户提供他们希望列表如何排序的一组选项。我能够很好地显示对话框,并且用户可以选择该选项。但是,一旦用户做出选择,我不确定如何在无法从 DialogFragment 类访问列表视图的“notifyDataSetChanged”方法的情况下刷新列表视图。我确实知道使用接口通过底层活动在两个片段之间进行通信,但我不清楚在这种特殊情况下如何应用该技术。我不确定我将在哪里定义我的接口以及谁将实现该接口。请多多包涵,因为我是一名新手 Android 开发人员,也是这个网站的发帖人。下面是我修改后的代码,只包含相关代码:

public class ListFrag extends SherlockListFragment {
    private ListFragListener myListener;
    private DatabaseAdapter database;
    private ArrayList<MyObject> listItems;
    private View layout;
    private Button confirmBtn;
    private Button cancelBtn;
    private boolean isDeleteActive;
    private boolean isExportActive;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        layout = inflater.inflate(R.layout.list_frag, container, false);    

        return layout;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        database = DatabaseAdapter.getInstance(getActivity());

        database.open();
        listItems = database.getMyObjects();
        database.close();

        setHasOptionsMenu(true);
        registerForContextMenu(this.getListView());

        final MyAdapter listAdapter = new MyAdapter(getActivity(), listItems);
        setListAdapter(listAdapter);

        confirmBtn = (Button) layout.findViewById(R.id.itemDelete);
        cancelBtn = (Button) layout.findViewById(R.id.itemCancel);

    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.listview_omenu, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        int itemId = item.getItemId();

        if (itemId == R.id.listOMItem3) {
            SortDialogFragment sortDialog = SortDialogFragment.newInstance(listItems);
            sortDialog.show(getFragmentManager(), "Sort Dialog");
        } 
        return true;
    }

    public static class SortDialogFragment extends SherlockDialogFragment {

        public static SortDialogFragment newInstance(ArrayList<MyObject> objectsToSort) {
            SortDialogFragment sortDialog = new SortDialogFragment();
            Bundle args = new Bundle();
            args.putParcelableArrayList("MyObjects to sort", objectsToSort);
            sortDialog.setArguments(args);
            return sortDialog;
        }

        @Override 
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

            final ArrayList<MyObjects> objectsToSort = getArguments().getParcelableArrayList("MyObjects to sort");


            builder.setTitle("Sort objects by...");
            builder.setSingleChoiceItems(R.array.sortDialogOptions, checkedItem, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub
                    if (which == 0) {
                        Collections.sort(objectsToSort, new ComparatorOne());
                    } else if (which == 1) {
                        Collections.sort(objectsToSort, new ComparatorTwo());
                    } else {
                        Collections.sort(objectsToSort, new ComparatorThree());
                    }

                    ?????????????????????????????????????
    // This is where I am trying to refresh the list before dismissing the dialog but I 
// I apparently do not have access to listview's adapter to call the "notifyDataSetChanged" method.


                    dialog.dismiss();
                }
            });

            builder.setPositiveButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });

            return builder.create();
        }
    }
}

【问题讨论】:

  • listview's "notifyDataSetChanged" method。 notifyDataSetChanged 方法来自适配器而不是列表视图。
  • FragmentManager.findFragmentByTag("thetagofListFrag") if != null 然后转换为 ListFrag ,现在你有了这个片段的实例

标签: java android android-fragments communication android-dialogfragment


【解决方案1】:

首先要刷新您的列表视图,您必须在您为列表视图设置的适配器上调用notifyDataSetChanged 。首先将final MyAdapter listAdapter 更改为字段而不是变量。

下一步是将适配器传递给对话框的构造函数并将其存储在字段中。 SortDialogFragment 的标题应如下所示:

 public static class SortDialogFragment extends SherlockDialogFragment {
    private MyAdapter mAdapter;
    public static SortDialogFragment newInstance(ArrayList<MyObject> objectsToSort, MyAdapter adapter) {
        SortDialogFragment sortDialog = new SortDialogFragment();
        sortDialog.setAdapter(adapter);
        Bundle args = new Bundle();
        args.putParcelableArrayList("MyObjects to sort", objectsToSort);
        sortDialog.setArguments(args);
        return sortDialog;
    }

    public void setAdapter (MyAdapter adapter){
         mAdapter = adapter;
    }
   (...)

接下来在创建 SortDialogFragment 时传递适配器。应该是这样的:

SortDialogFragment sortDialog = SortDialogFragment.newInstance(listItems, listAdapter);

最后你只需要在????????????????上拨打mAdapter.notifyDataSetChanged();

【讨论】:

  • 您好,首先感谢您的快速回复。我已经按照您建议的方式修改了我的代码,但是在我的 SortDialogFragment 类中出现以下错误:“避免在片段中使用非默认构造函数:请改用默认构造函数加上 Fragment#setArguments(Bundle)”。我会尝试通过 Fragment setArguments 方法发送我的适配器,但我认为我不能这样做,因为 BaseAdapter 不可打包。
  • 再次非常感谢。解决方案就像魅力一样。我没有想到使用 setter 方法解决问题。我把它弄得太复杂了。无论如何,我确实学到了一些东西。谢谢
  • 没问题的朋友。请记住将解决方案标记为帮助其他人的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多