【问题标题】:Handle Fragments from ViewPager when orientation changes当方向改变时处理来自 ViewPager 的片段
【发布时间】:2016-08-17 21:43:39
【问题描述】:

从今天早上开始,我一直在尝试使用 viewpager 处理屏幕旋转,我尝试了很多东西,我在这里阅读了几乎所有关于此的帖子,但我无法找到我的问题。

问题

  1. 当我改变方向时,它会删除 3 或 4 页,我必须向右滑动 3 或 4 次才能看到其他页面。几乎每次都从纵向切换到纵向,没有页面被删除,但是如果我从纵向切换到横向,页面就会消失

我在其中一篇文章中读到,这是由于当方向改变时片段被破坏,我们需要使用 setRetainInstance(true);在里面创建来解决这个问题,但它不起作用,我在这里遗漏了什么吗?

    public class SectionsPagerAdapter extends FragmentStatePagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        if (position <= (arraySize - 1)) {
            HashMap<String, String> data = computeQuestion(questoes[randomize.get(position)]);
            return PlaceholderFragment.newInstance(position + 1, data, tables[randomize.get(position)]);
        } else {
            return FragmentResultados.newInstance(position + 1);
        }
    }

    @Override
    public int getCount() {
        return arraySize + 1; // number of pages + ending page
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "SECTION 1";
            case 1:
                return "SECTION 2";
            case 2:
                return "SECTION 3";
            default:
                return String.valueOf(position);
        }
    }
    }

片段

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

编辑

片段

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

        mViewPager = (ViewPager) getActivity().findViewById(R.id.container);
        mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
        mViewPager.setAdapter(mSectionsPagerAdapter);
        return rootView;
    }

结果:IllegalStateException:FragmentManager 已经在执行事务

活动

 private static ViewPager mViewPager;
 private static FragmentStatePagerAdapter mSectionsPagerAdapter;  

      @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_exame2);
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    }

清单

 <activity
        android:name=".Exame"
        android:label="@string/title_activity_exame"
        android:theme="@style/AppTheme"
        android:configChanges="keyboardHidden|orientation|screenSize"/>

activity_xml

<android.support.design.widget.CoordinatorLayout      xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="pt.condutorresponsavel.android.testescodigo.Exame">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.view.ViewPager
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<ImageView
    android:id="@+id/arrowLeft"
    android:background="@color/colorPrimary"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_first_page_white_24dp"
    android:paddingLeft="10dp"
    android:paddingTop="3dp"
    android:paddingRight="10dp"
    android:paddingBottom="3dp"
    android:onClick="toFirst"
   />

<ImageView
    android:background="@color/colorPrimary"
    android:onClick="toLast"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_last_page_white_24dp"
    android:paddingLeft="10dp"
    android:paddingTop="3dp"
    android:paddingRight="10dp"
    android:paddingBottom="3dp"
    android:layout_alignParentRight="true"
    android:id="@+id/arrowRight" />

<TextView
    android:id="@+id/timeleft"
    android:textColor="#ffffff"
    android:background="@color/colorPrimary"
    android:paddingRight="10dp"
    android:paddingLeft="5dp"
    android:gravity="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="20:01"
    android:layout_alignBottom="@+id/arrowRight"
    android:layout_toLeftOf="@+id/arrowRight"
    android:layout_toStartOf="@+id/arrowRight"
    android:layout_alignParentTop="true" />

我将代码示例上传到github

已修复

private void InitializeUI(){
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.activity_exame2);
    InitializeUI();
}

【问题讨论】:

  • 为什么你在 fragment 中调用 getActivity().findViewById() 而不使用 rootView.findViewById() ?
  • 当你旋转屏幕时,整个 Activity 销毁,所以你应该将 ViewPager 的当前索引存储在 saveInstance 中并在 onCreate 中检索它。
  • 我正在使用 getActivity,因为如果我使用 rootView 返回 null,则 viewpager 在 activity_layout 内,而不是在 fragment_layout 内,这是我不理解他们使用的每个示例的事情之一rootView,活动不会被破坏 onCreate 我只调用一次,我在 InitializeUI() 中重置视图,我有一个计时器,显示 onCreate 内的时间限制,当方向改变时,时间保持不变。我更新了 github 文件,这只是一个示例,我有将近 2k 行的内容与此无关,但我可以发布完整的代码

标签: android


【解决方案1】:

你使用android支持库吗?这可能是一个问题。还可以在这里查看类似的问题: ViewPager fragments disappear when change screen rotation

【讨论】:

  • 我对此失去了所有希望,我尝试了该帖子上的所有遮阳篷,但都没有工作,是的,我正在使用支持库
  • 这里有一个类似的问题。应该用getChildFragmentManager,好像stackoverflow.com/questions/25216464/…
  • 非常感谢您的帮助,但是这个 setAdapter(adapter);总是抛出一个 IllegalStateException 说 FragmentManager 已经在执行事务
  • @tiago-oliveira 另外,尝试在 AndroidManifest.xml 中添加:android:configChanges="screenSize|orientation"
  • 我终于能够解决这个问题 :D,所以我从片段中删除了 setAdapter,并将它放在 InitializeUI() 中,就像一个魅力一样
【解决方案2】:

如果您的片段页面消失,那么它将起作用:-

在 ViewPagerAdapter 类中重写 getItemId(int position) 方法,如下所示:

@Override
public long getItemId(int position) {
    return System.currentTimeMillis();
}

【讨论】:

    【解决方案3】:

    我知道真的很晚了。对于其他遇到此问题的人,我也遇到了同样的问题:我使用 this 修复了它。

    【讨论】:

    • 如果你能把这个添加为评论就更好了
    • 欢迎来到 SO。请注意,仅链接的答案不符合 SO 的质量标准。看看这里:stackoverflow.com/help/how-to-answer
    【解决方案4】:

    我在清单文件中缺少android:configChanges="orientation|screenSize"。例如:

    <activity
        android:name=".MyActivity"
        android:configChanges="orientation|screenSize" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多