Android ViewPager中的片段将丢失其视图
我使用Android Studio的选项卡式活动启动了一个新项目。它创建了一个带有ViewPager和3个片段的活动=fragment1、fragment2和fragment3。 我将fragment1更改为具有listView和TextView,在创建片段时初始化它们。listView中的数据是从SQL数据库读取的。 当应用程序启动时,显示fragment1,listView显示从SQL读取的数据。 当我从fragment1滑动到fragment2并返回时,fragment1会正确地显示listview。然而,当我滑动到fragment3并返回fragment1时,listview数据丢失,我得到一个空白屏幕,尽管textview显示正确。 当我将应用程序更改为只有2个片段时,不会发生这种情况,我可以多次从fragment1滑动到fragment2并返回,而不会丢失任何数据。当我添加第三个片段时,数据在第一次滑动到fragment3时丢失,但如果我仅在Fragment1和fragment2之间滑动,数据不会丢失。Android ViewPager中的片段将丢失其视图,android,listview,android-fragments,Android,Listview,Android Fragments,我使用Android Studio的选项卡式活动启动了一个新项目。它创建了一个带有ViewPager和3个片段的活动=fragment1、fragment2和fragment3。 我将fragment1更改为具有listView和TextView,在创建片段时初始化它们。listView中的数据是从SQL数据库读取的。 当应用程序启动时,显示fragment1,listView显示从SQL读取的数据。 当我从fragment1滑动到fragment2并返回时,fragment1会正确地显示lis
知道为什么会这样吗?问题解决了。正如@Daniel Nugent所指出的,问题是适配器在内存中保留了3个片段。页面中的数据是从DB加载的,因此当重新创建视图时,当用户滑动时片段被破坏并重新创建时,listview适配器丢失了数据,必须重新填充它。这个问题不会出现在简单的示例中,因为通常显示的数据是静态的,并且是在onCreateView方法中加载的。出现这种情况是因为默认情况下
ViewPager
有一个名为setOffscreenPageLimit(int i)
的函数。这会告诉ViewPager
需要在内存中存储多少片段。默认情况下,它是“2”。因此,当您从片段1滑动到片段2时,它仍将片段1保留在内存中,并且不会从内存中销毁它。但是当您滑动到片段3时,它将在内存中有片段2和片段3,因此它将删除片段1
这就是为什么当您返回到第一个片段时,它会丢失其视图或数据
尝试使用
mViewPager.setOffscreenPageLimit(your total fragment count +1);
或更好的解决方案
当您在ViewPager
中滑动时,不要替换您的片段<代码>将其推到后退,当您返回时,检查是否有后退,如果有碎片,则只需将其弹出并显示
代码如下:
public void pushFragments(String tag, Fragment fragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (manager.findFragmentByTag(tag) == null) {
ft.add(R.id.frame_container, fragment, tag);
}
String tagOne="com........Frag_one"; //your fragment class name
String tagTwo="com........Frag_two";
String tagThree="com........Frag_three";
String tagFour="com........Frag_profile";
Fragment fragmentOne = manager.findFragmentByTag(tagOne);
Fragment fragmentTwo = manager.findFragmentByTag(tagTwo);
Fragment fragmentThree = manager.findFragmentByTag(tagThree);
Fragment fragmentFour = manager.findFragmentByTag(tagFour);
manager.executePendingTransactions();
// Hide all Fragment
if (fragmentOne != null) {
ft.hide(fragmentOne);
}
if (fragmentTwo != null) {
ft.hide(fragmentTwo);
}
if (fragmentThree != null) {
ft.hide(fragmentThree);
}
if (fragmentFour != null) {
ft.hide(fragmentFour);
}
// Show current Fragment
if (tag.equals(tagOne)) {
if (fragmentOne != null) {
ft.show(fragmentOne);
}
}
if (tag.equals(tagTwo)) {
if (fragmentTwo != null) {
ft.show(fragmentTwo);
}
}
if (tag.equals(tagThree)) {
if (fragmentThree != null) {
ft.show(fragmentThree);
}
}
if (tag.equals(tagFour)) {
if (fragmentFour != null) {
ft.show(fragmentFour);
}
}
ft.commit();
}
Fragment fragment = new Frag_one();
pushFragments(fragment.getClass().getName(),fragment);
以下是您如何称呼它:
public void pushFragments(String tag, Fragment fragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (manager.findFragmentByTag(tag) == null) {
ft.add(R.id.frame_container, fragment, tag);
}
String tagOne="com........Frag_one"; //your fragment class name
String tagTwo="com........Frag_two";
String tagThree="com........Frag_three";
String tagFour="com........Frag_profile";
Fragment fragmentOne = manager.findFragmentByTag(tagOne);
Fragment fragmentTwo = manager.findFragmentByTag(tagTwo);
Fragment fragmentThree = manager.findFragmentByTag(tagThree);
Fragment fragmentFour = manager.findFragmentByTag(tagFour);
manager.executePendingTransactions();
// Hide all Fragment
if (fragmentOne != null) {
ft.hide(fragmentOne);
}
if (fragmentTwo != null) {
ft.hide(fragmentTwo);
}
if (fragmentThree != null) {
ft.hide(fragmentThree);
}
if (fragmentFour != null) {
ft.hide(fragmentFour);
}
// Show current Fragment
if (tag.equals(tagOne)) {
if (fragmentOne != null) {
ft.show(fragmentOne);
}
}
if (tag.equals(tagTwo)) {
if (fragmentTwo != null) {
ft.show(fragmentTwo);
}
}
if (tag.equals(tagThree)) {
if (fragmentThree != null) {
ft.show(fragmentThree);
}
}
if (tag.equals(tagFour)) {
if (fragmentFour != null) {
ft.show(fragmentFour);
}
}
ft.commit();
}
Fragment fragment = new Frag_one();
pushFragments(fragment.getClass().getName(),fragment);
如果没有一个可复制的例子,就不可能确切地说出它发生的原因。两个片段没有出现问题的原因是FragmentPagerAdapter使两个片段都保持活动状态,请参见此处:和此处:项目太大,无法发布。如果我们不能很快找到解决方案,我将创建一个小版本发布。该项目太大,无法发布。如果我们不能很快找到解决方案,我将创建一个小版本发布。无论如何,我进一步测试后发现,listview丢失了它的适配器(listview.getAdapter()返回null)。因此,在重新显示页面之前,我现在测试这种情况,如果它存在,我重新创建适配器,并且正确显示列表。这能给你们一个关于发生了什么的提示吗?我解决了这个问题。