Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/218.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android ViewPager中的片段将丢失其视图_Android_Listview_Android Fragments - Fatal编程技术网

Android ViewPager中的片段将丢失其视图

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

我使用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之间滑动,数据不会丢失。
知道为什么会这样吗?

问题解决了。正如@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)。因此,在重新显示页面之前,我现在测试这种情况,如果它存在,我重新创建适配器,并且正确显示列表。这能给你们一个关于发生了什么的提示吗?我解决了这个问题。