【问题标题】:Handling Screen Rotation for Fragment inside of View(State)PagerAdapter inside Fragment处理 Fragment 内 View(State)PagerAdapter 内 Fragment 的屏幕旋转
【发布时间】:2015-11-21 23:05:38
【问题描述】:

你好类(android)程序员,

情况如下:

我有一个使用 NavigationDrawer 的活动,它允许加载 3 个片段。在其中一个片段中,我有一个 ViewStatePagerAdapter,它又承载了 3 个片段。在其中一个片段中,我使用游标加载器加载了一堆数据库数据。这些值可编辑为新值,但在单击某个按钮之前不应保留到 DB。

这一切都很好,但问题是当我现在旋转屏幕时,所有更改的数据都消失了。我尝试在内部片段本身中使用 onSaveInstance,但我认为问题更高,因为我已经注意到,当我旋转屏幕时,viewpager 会跳回第一个选项卡。

什么是正确的方式(/正确的位置:活动,某些片段,...):

  1. 确保查看器保持在右侧选项卡上
  2. 记住内部片段中更改的数据

包含 viewpager 的片段当前有以下 onCreateView :

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

    View v =  inflater.inflate(R.layout.fragment_home, null);
    tabLayout = (TabLayout) v.findViewById(R.id.fragment_tabs);
    viewPager = (ViewPager) v.findViewById(R.id.fragment_viewpager);
    viewPager.setOffscreenPageLimit(3);

    viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
    tabLayout.setupWithViewPager(viewPager);

    return v;
}

以及 FragmentStatePagerAdapter 的内部类

 class MyAdapter extends FragmentStatePagerAdapter {

    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

    /**
     * Return fragment with respect to Position .
     */
    @Override
    public Fragment getItem(int position)
    {
        switch (position){
            case 0 : return PersonFragment.newInstance();
            case 1 : return FriendsFragment.newInstance();
            case 2 : return EventsFragment.newInstance();
        }
        return null;
    }

    @Override
    public int getCount() {
        return int_items;
    }

    /**
     * This method returns the title of the tab according to the position.
     */
    @Override
    public CharSequence getPageTitle(int position) {

        switch (position){
            case 0 :
                return "ME";
            case 1 :
                return "FOLLOWING";
            case 2 :
                return "EVENTS";
        }
        return null;
    }
}

这里的其他人没有什么特别的事情发生。 (也许应该?)

viewpager 内部的片段有以下 onCreate/onCreateView

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

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

    View rootView = inflater.inflate(R.layout.fragment_person, container, false);
    this.viewHolder = new ViewHolder(rootView);

    if (savedInstanceState != null) {
        CharSequence savedPersonName = savedInstanceState.getCharSequence("personName");
        if (savedPersonName != null) {
            Log.v("PersonFragment", savedPersonName.toString());
            this.viewHolder.personnameView.setText(savedPersonName);
        }
    }

    return rootView;
}

提前致谢。

【问题讨论】:

  • 发布一些代码。您的浏览器在创建时做什么?它是获取现有片段的实例,还是完全创建一个新片段。片段的 onCreate 中有什么。
  • @QuantumTiger 来了,已经加了一部分,还要加更多。
  • 在哪里重新加载保存的实例状态
  • 我不再这样做了,因为它使应用程序崩溃,就像我做的那样。这就是为什么我想知道我应该在哪里以及如何做到这一点。在 viewpager 片段中,我使用 onSaveInstanceState 将数据添加到 outState 包中,并在 onActivityCreated 中检查它是否为空,如果不是,则从中取出我的数据。
  • 嗯,如果这样做,我的数据是否有可能被传递,但 GUI 只是没有更新?

标签: java android android-fragments


【解决方案1】:

您可能已经知道这一点,但我会这样做来解决您的第二个问题

private TextView tvTitle;

public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    rootView = inflater.inflate(R.layout.mylayout, container, false);

    tvTitle = (TextView) rootView.findViewById(R.id.mytitle);

    if (savedInstanceState != null) {
      CharSequence csTitle = savedInstanceState.getCharSequence("myTitle");
      if (csTitle != null) tvTitle.setText(csTitle);
    }
}

public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);

outState.putCharSequence("myTitle", tvTitle.getText());
}

【讨论】:

  • 所以我这样做了,甚至将值发送到 logcat,正确的值显示在那里。在同一个 if 语句中,我使用了 setText,但我没有看到它在 GUI 中发生变化。我更新了我现在在原始帖子中使用的 onCreateView,所以你可以看到。
  • 因此看起来正在查看的片段与写入 logcat 的片段不同。 Nguyen 上面的回答有帮助吗?
  • 我想我已经修好了,不过我暂时删除了一些东西,所以可能会再次出现一些错误。似乎问题在于,在我的 mainActivity 中,我每次都创建了一个新的 HomeFragment,而不是首先检查是否存在一个(通过使用 findFragmentByTag)。我想这使得它的所有孩子也消失了,包括 ViewPager 和那个里面的片段。感谢您花时间帮助我,非常感谢。
  • 很高兴你找到了它。整个片段,寻呼机的事情记录得很少,恕我直言
  • 我试图找到一些关于它是如何工作的不错的文档,是的,但没有太多成功。我想最好的方法是阅读它的源代码......
猜你喜欢
  • 1970-01-01
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多