页面查看器中的片段替换不适用于 API 21
Fragment replace in a page viewer not working on API 21
我有一个页面查看器,API 21 上发生了一些非常奇怪的事情(它适用于 API 17)。
在查看器的第一页上有一个 link 加载第二页并替换其中的片段。我第一次单击 link 并加载第二页它工作正常,但如果我在加载第三页后单击 link,片段替换不起作用,我最终得到第二个屏幕没有片段。
这是设置第二页的代码的简化版本:
ScreenSlidePagerAdapter adapter = (ScreenSlidePagerAdapter) sPager.getAdapter();
// Set second page in the viewer
if (adapter.getCount() != 2) {
adapter.setCount(2);
adapter.notifyDataSetChanged();
}
SecondPageFragment frag2 = new SecondPageFragment();
sFragmentManager.beginTransaction().replace(R.id.container_page2, frag2, “Frag2TAG”).commit();
sPager.setCurrentItem(1);
为什么与 API 17 相比,替换在 API 21 上的工作方式不同?以前有人遇到过类似的问题吗?这似乎是相关的,但没有解决方案:fragments-transaction-replace-on-api-21-is-staying-behind
编辑:SecondPageFragment 的代码只是一个片段:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved_instance_state) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_page2, container, false);
return rootView;
}
这是布局 fragment_page2:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/container_page2">
方法getSupportFragmentManager
()引用目录android/support/v4/...
由于 sFragmentManager
是使用 getSupportFragmentManager
() 创建的,您应该检查对 Fragment 的所有引用,看看它们是否引用相同的 support/v4 目录。一种快速的方法是检查 android.support.v4 的导入。您也可以通过单击所有对 Fragment 的引用来检查。
另一种选择是不使用 "support" 包。
对于调试,我建议使用 FragmentTransaction 的 addToBackStack
()。这会保存在堆栈中处于活动状态的片段的数据和状态。这将有利于代码检查,并可能因保存状态而产生积极影响。
您也可以在代码 commit
() 之后调用 FragmentManager 的 getBackStackEntryCount
()。为此,您必须分解代码 sFragmentManager.beginTransaction().replace(R.id.container_page2, frag2, “Frag2TAG”).commit()
。但是应该不会太难。
新关联!在我看来 FragmentPagerAdapter class 中有一个错误。看看 SO link @ Replace Fragment inside a ViewPager。由于您对 "The first time I click the link and load the second page It works fine..." 的评论,我认为它与 getItemId
() 有关,可能必须覆盖它。
就我个人而言,我在 Fragment 中使用了 PagerAdapter,将来可能会使用 FragmentPagerAdapter,因为它结合了两个 class 并且应该更容易。
编辑:
您的 ID container_page2
可能使用了正确的表单和布局文件。但是,如果你想将它与 replace() 一起使用,你应该使用相同的一致 UI 元素 ID。否则 FragmentManager 将根据容器视图 ID 管理片段,这让我很困惑。
我有片段的布局示例。它是 sample_content_fragment
,一个 FrameLayout,嵌套在一个 LinearLayout 中。
Fragment 的示例布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sample_main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<FrameLayout
android:id="@+id/sample_content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
随时通知我们。我想知道。
我有一个页面查看器,API 21 上发生了一些非常奇怪的事情(它适用于 API 17)。
在查看器的第一页上有一个 link 加载第二页并替换其中的片段。我第一次单击 link 并加载第二页它工作正常,但如果我在加载第三页后单击 link,片段替换不起作用,我最终得到第二个屏幕没有片段。
这是设置第二页的代码的简化版本:
ScreenSlidePagerAdapter adapter = (ScreenSlidePagerAdapter) sPager.getAdapter();
// Set second page in the viewer
if (adapter.getCount() != 2) {
adapter.setCount(2);
adapter.notifyDataSetChanged();
}
SecondPageFragment frag2 = new SecondPageFragment();
sFragmentManager.beginTransaction().replace(R.id.container_page2, frag2, “Frag2TAG”).commit();
sPager.setCurrentItem(1);
为什么与 API 17 相比,替换在 API 21 上的工作方式不同?以前有人遇到过类似的问题吗?这似乎是相关的,但没有解决方案:fragments-transaction-replace-on-api-21-is-staying-behind
编辑:SecondPageFragment 的代码只是一个片段:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved_instance_state) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_page2, container, false);
return rootView;
}
这是布局 fragment_page2:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/container_page2">
方法getSupportFragmentManager
()引用目录android/support/v4/...
由于 sFragmentManager
是使用 getSupportFragmentManager
() 创建的,您应该检查对 Fragment 的所有引用,看看它们是否引用相同的 support/v4 目录。一种快速的方法是检查 android.support.v4 的导入。您也可以通过单击所有对 Fragment 的引用来检查。
另一种选择是不使用 "support" 包。
对于调试,我建议使用 FragmentTransaction 的 addToBackStack
()。这会保存在堆栈中处于活动状态的片段的数据和状态。这将有利于代码检查,并可能因保存状态而产生积极影响。
您也可以在代码 commit
() 之后调用 FragmentManager 的 getBackStackEntryCount
()。为此,您必须分解代码 sFragmentManager.beginTransaction().replace(R.id.container_page2, frag2, “Frag2TAG”).commit()
。但是应该不会太难。
新关联!在我看来 FragmentPagerAdapter class 中有一个错误。看看 SO link @ Replace Fragment inside a ViewPager。由于您对 "The first time I click the link and load the second page It works fine..." 的评论,我认为它与 getItemId
() 有关,可能必须覆盖它。
就我个人而言,我在 Fragment 中使用了 PagerAdapter,将来可能会使用 FragmentPagerAdapter,因为它结合了两个 class 并且应该更容易。
编辑:
您的 ID container_page2
可能使用了正确的表单和布局文件。但是,如果你想将它与 replace() 一起使用,你应该使用相同的一致 UI 元素 ID。否则 FragmentManager 将根据容器视图 ID 管理片段,这让我很困惑。
我有片段的布局示例。它是 sample_content_fragment
,一个 FrameLayout,嵌套在一个 LinearLayout 中。
Fragment 的示例布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/sample_main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<FrameLayout
android:id="@+id/sample_content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
随时通知我们。我想知道。