Java 如何理解getFragments.size()在TabLayout中有3个选项卡,每个选项卡都显示正确的片段时,给了我2个?

Java 如何理解getFragments.size()在TabLayout中有3个选项卡,每个选项卡都显示正确的片段时,给了我2个?,java,android,android-fragments,android-tablayout,fragmentpageradapter,Java,Android,Android Fragments,Android Tablayout,Fragmentpageradapter,我已经用FragmentPagerAdapter和3个fragments通过ViewPager创建了3个选项卡。滑动到第三个选项卡,断开第一个选项卡的一位,并更改片段的索引 我已经用FragmentPagerAdapter和3个fragments通过ViewPager创建了3个选项卡。片段正常,活动在重新启动时正确显示所有内容,但我注意到一个错误,当我刷到第三个选项卡,然后又刷回第一个选项卡时,第一个选项卡会丢失一些信息。当我重新启动活动时,第一个选项卡返回正确的信息。但每次我转到第三个,然后又

我已经用FragmentPagerAdapter和3个fragments通过ViewPager创建了3个选项卡。滑动到第三个选项卡,断开第一个选项卡的一位,并更改片段的索引

我已经用FragmentPagerAdapter和3个fragments通过ViewPager创建了3个选项卡。片段正常,活动在重新启动时正确显示所有内容,但我注意到一个错误,当我刷到第三个选项卡,然后又刷回第一个选项卡时,第一个选项卡会丢失一些信息。当我重新启动活动时,第一个选项卡返回正确的信息。但每次我转到第三个,然后又回到第一个,都会丢失它。我应用了一种解决方法,刷新fragment的onResume中丢失的部分,效果很好。但我仍然对此感到困惑,并试图找出为什么会发生这种情况

我已经检查了网络上的各种来源,并且多次检查了我的代码,但是我不知道是什么导致了这个问题。 然而,我注意到,当我在活动中运行tabs.getTabCount时,它显示为3,但FragmentManager getFragments.size令人惊讶地显示为2,当所有三个选项卡和片段都在活动中可见时。它还显示,当我滑动到第三个选项卡时,片段的索引发生了变化:我预计,tab1在0,tab2在1,tab3在2,这是FragmentManager在我滑动到tab3之前根本看不到tab1和tab2 tab3的情况,然后索引被反转:tab1在1,tab2在0,尽管在活动中可见,但表3仍然不存在

我没有收到任何错误消息

//我的活动中有这个 SectionsPagerAdapter SectionsPagerAdapter=新SectionsPagerAdapterthis,getSupportFragmentManager; ViewPager ViewPager=findviewbydr.id.view\u pager; viewPager.setAdaptersectionsPagerAdapter; TabLayout tabs=findviewbydr.id.tabs; tabs.setupwithviewpagerviewpage; //这是我的碎纸机 公共类节SpagerAdapter扩展了FragmentPagerAdapter{ 私有静态最终int NUM_TABS=3; @斯特林格斯 私有静态final int[]TAB_TITLES=new int[]{R.string.TAB_text_1,R.string.TAB_text_2,R.string.TAB_text_3}; 私有最终上下文mContext; 私人最终碎片管理器fm; 公共部分SpagerAdapterContext,FragmentManager fm{ superfm,行为\u恢复\u仅\u当前\u片段; mContext=上下文; this.fm=fm; } @凌驾 公共片段getItemint位置{ //调用getItem来实例化给定页面的片段。 //返回下面定义为静态内部类的占位符片段。 //返回占位符fragment.newInstanceposition+1; 片段frag=null; 开关位置{ 案例0: frag=新的检查片段; 打破 案例1: frag=新的结核菌素片段; 打破 案例2: frag=新发现的碎片; 打破 } 返回碎片; } @可空 @凌驾 公共字符序列getPageTitleint位置{ 返回mContext.getResources.getStringTAB_标题[位置]; } @凌驾 公共整数getCount{ 返回NUM_标签; } } //不确定为三个片段加上它们的布局文件包含代码是否有意义,我检查了它们,它们非常简单,我没有看到任何会导致问题的东西。。。 我希望getFragments.size给我3,而不会丢失一点tab1和重新索引


如果有人对这个或类似的问题有任何看法,或者对如何找到问题的根源有任何想法,我将不胜感激。

基本上,这种情况会发生,因为适配器只对片段进行强引用。 当您在第一个片段上时,它存储1,2个片段。 当您在第三个片段上时,它存储3,2个片段。
因此,如果您在中间片段上调用getFragments,90%这个方法将返回3

以防万一有人发现自己的处境与我相似:

萨马伦库为我的上述问题提供了答案,但这是我问题的一部分。第二部分是,当我刷到tab3时,我正在丢失tab1中的数据

我找到了一个解决办法,但不是一个合适的解决办法。现在,我知道了答案:这是因为当tab3显示时适配器不再引用tab1,当我从tab3滑回tab1时,适配器提供了一个新的tab1实例,该实例在创建时由片段中的代码部分填充,但其余数据(如微调器值等)丢失

我已通过设置:viewPager.setOffscreenPageLimit3修复了此问题;现在适配器将片段保存在内存中


有关更多详细信息,请参见此链接:

Brilliant!:非常感谢你的这次演讲 我的回答是不客气的。我现在可以看到索引的变化是由于这个“可见性”的东西:当tab3被激活时,tab2为0,tab3为1,然后当我滑动到tab2时,它的索引位置没有改变,但tab1再次显示并插入到2,然后当我滑动到tab1时,tab3消失,只留下tab2为0,tab1为1。就这样!
This is my gradle module:app

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.sasa.spcsinspections"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }
    buildTypes {
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility = '1.8'
        targetCompatibility = '1.8'
    }

    dataBinding{
        enabled true
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.google.android.material:material:1.1.0-alpha02'
    implementation 'androidx.annotation:annotation:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
    implementation 'androidx.preference:preference:1.1.0-alpha05'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.recyclerview:recyclerview:1.1.0-alpha06'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.9.1'
    implementation "androidx.room:room-runtime:$rootProject.roomVersion"
    annotationProcessor "androidx.room:room-compiler:$rootProject.roomVersion"
    androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
    implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.archLifecycleVersion"
    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$rootProject.archLifecycleVersion"
}