在活动和片段之间传递数据或行为

3
我有这样的结构:
Activity A有一个ViewPager。ViewPager的页面上有多个Fragment。
Activity A有一个复杂对象列表,我想在这些页面上显示出来。
当用户在ViewPager中点击一个项目时,Activity B必须启动。Activity B还需要具有这个复杂对象的列表。
所以我必须传递这个列表。
A-> Fragment(s)->B
首先我发现不能使用fragment的构造函数来传递数据到它。我必须使用parcelable或serializable。在片段中,我必须再次进行打包或序列化以传递给B。
但是我不想将整个复杂数据列表序列化或打包两次,只为了将其传递给B。
我想避免使用静态字段。
然后我想到了将监听器传递给片段,该监听器侦听项单击,并通知我的Activity A,然后Activity A使用数据启动Activity B。对我而言,这看起来最干净,因为实际上数据属于A,因此A使用数据启动片段,片段返回A,然后A使用数据启动B。我不必随处传递数据(序列化!)。
但是这似乎行不通,因为我如何使用序列化来将侦听器传递给片段?使用片段中的侦听器回到活动有什么问题?
我该如何解决这个问题?
编辑
我在一个关于对话框片段的线程中找到了这个解决方案:Get data back from a fragment dialog - best practices?
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
    mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
    throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}

我在我的片段中添加了这个,并让我的活动实现特定的接口。这将解决从片段传递数据到B的问题。但我仍然需要将A中的列表传递给片段。可能我需要使用Parcelable...
编辑:我尝试过Parcelable,它可以工作。但是我的列表中的对象之间有很多字段,也有地图等内容。编写Parcelable代码(写/读)非常麻烦。也许我只需要坚持静态数据...

我遇到了同样的问题。我的复杂数据通过一个片段在活动A中计算和显示在列表中,但是详细信息将在活动B中使用一个片段或者在同一活动中的两个面板布局中显示,但是使用不同的详细信息片段。我完全不知道该怎么办,只能将我的详细数据打包成可传递对象,这很麻烦...你有更好的想法吗?例如将其放入应用程序对象作为中间介质? - Zordid
1个回答

2
你找到的监听器解决方案非常出色,实际上是谷歌推荐的(http://developer.android.com/training/basics/fragments/communicating.html)。
至于你剩余的将数据传递给片段的问题,你确定需要传递整个列表而不是ViewPager中每个片段的列表元素吗?如果你只需要一个元素,可以像这样做:
    /*
     * An adapter for swiping through the fragments we have.
     */
    private class CustomPagerAdapter extends FragmentStatePagerAdapter {

        List<Thing> things;

        public CustomPagerAdapter(FragmentManager fragmentManager, List<Thing> things) {
            super(fragmentManager);
            this.things = things;
        }

        @Override
        public int getCount() {
            return things.size();
        }

        @Override
        public Fragment getItem(int position) {
            return ThingFragment.newInstance(things.get(position));
        }
    }

    /*
     * Loads a view based on the thing.
     */
    private static class ThingFragment extends Fragment {

        private String name;

        static ThingFragment newInstance(Thing thing) {

            ThingFragment f = new ThingFragment();

            // add some arguments to our fragment for onCreateView
            Bundle args = new Bundle();
            args.putString("name", thing.getName());
            f.setArguments(args);

            return f;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            name = getArguments().getString("name");
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View v = inflater.inflate(R.layout.thing_fragment_layout, container, false);
                    TextView t = (TextView)v.findViewById(R.id.thingText);
            t.setText(name);
            return v;
        }
    }

将您的列表传递给适配器。当然,这需要动态创建您的动态,但填充xml片段非常容易。

如果您确实需要传递整个列表,则可能必须使各个复杂对象可 Parcelable,并像使用Bundle.putParcelableArray()一样将其添加到Fragment args中。


感谢您的回答。在每个片段中,我都要显示一个网格,并且我想将模型项列表传递给网格。我尝试了Parcelable,但实现非常糟糕(我的数据类型有很多字段,还有map类型等,编写序列化和反序列化代码真的很痛苦)。而且它也非常慢,我的屏幕要空白一段时间。所以我想我必须使用静态数据。 - User
抱歉,屏幕空白是因为其他问题,而不是可序列化对象。 - User
1
我想,假设您对自己的条件有把握,您可以通过强制转换在onAttach中获取信息:@Override public void onAttach(Activity activity) { super.onAttach(activity); mFragmentList = ((MyActivity)activity).getList(); } - Makario

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接