3

我有这个结构:

活动 A 有一个 ViewPager。ViewPager 的页面称为片段。

活动 A 有一个复杂对象的列表,我想在页面中显示这些对象。

当用户单击 ViewPager 活动 B 中的项目时,必须启动。活动 B 还需要包含复杂对象的列表。

所以我必须通过这个列表

A -> 片段 -> B

首先,我发现无法使用片段的构造函数将数据传递给它。我必须使用可打包或可序列化的。在片段中,我必须再次打包或序列化以传递给 B。

但我不想序列化或打包整个复杂数据列表 2 次,只是为了将其传递给 B。

我想避免使用静态字段。

然后我想到将一个侦听器传递给片段,该片段侦听项目点击,并通知我的活动 A 和活动 A,然后使用数据启动活动 B。这对我来说看起来最干净,因为 A 实际上是数据所属的,所以 A 从数据开始片段,片段回到 A,然后 A 从数据开始 B。我不必到处传递数据(序列化!)。

但这似乎不起作用,因为如何使用序列化将侦听器传递给片段?在片段中使用监听器返回活动有什么问题?

我该如何解决这个问题?

编辑

我在关于对话片段的线程中找到了这个解决方案:Get data back from a fragment dialog - best practice?

@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 代码(写/读)是一种痛苦。也许我只是坚持静态数据......

4

1 回答 1

2

您找到的侦听器解决方案非常出色,实际上是 Google 推荐的 ( 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。

于 2012-06-21T10:29:33.250 回答