首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android ViewPager 2-片段不再存在

Android ViewPager 2-片段不再存在
EN

Stack Overflow用户
提问于 2022-05-07 22:28:19
回答 1查看 598关注 0票数 1

我有一个应用程序,其中一个主片段包含一个与ViewPager2绑定的选项卡布局,以便在三个不同的片段之间导航。当我旋转手机屏幕时,应用程序会出现以下错误:

键f#0不再存在片段:惟一id c4576c9c-4bbd-4dc0-a304-b86653ed2820 (文章末尾的完全错误堆栈)

这是我的设计:

activity_main.xml

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:id="@+id/main_activity_coordinator"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical">
    <com.google.android.material.appbar.AppBarLayout
        app:layout_constraintTop_toTopOf="parent"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:id="@+id/app_bar"
        android:theme="@style/Theme.VirtualGymBuddy.AppBarOverlay"
    >

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:title="@string/app_name" />


    </com.google.android.material.appbar.AppBarLayout>


    <androidx.fragment.app.FragmentContainerView
        android:tag="MAIN-FRAG"
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph"
        />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

main_fragment.xml

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:tag="MAIN-FRAG"
    android:id="@+id/main_relative_layout"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:paddingTop="?attr/actionBarSize"
    xmlns:tools="http://schemas.android.com/tools">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabTextAppearance="@style/MyTabLayoutStyle"
        >

        <com.google.android.material.tabs.TabItem
            android:id="@+id/tab1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/tab1" />

        <com.google.android.material.tabs.TabItem
            android:id="@+id/tab2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/tab2" />

        <com.google.android.material.tabs.TabItem
            android:id="@+id/tab3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/tab3" />

    </com.google.android.material.tabs.TabLayout>
        <androidx.viewpager2.widget.ViewPager2
            android:layout_below="@id/tabBar"
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
        />
</RelativeLayout>

content_main.xml

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/content_main_constraint"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <fragment
        android:id="@+id/nav_host_fragment_content_main"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

ActivityMain.java

代码语言:javascript
运行
复制
public class MainActivity extends AppCompatActivity {
    private AppBarConfiguration appBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(null);
        setContentView(R.layout.activity_main);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }

}

MainFragment.java

代码语言:javascript
运行
复制
public class MainFragment extends Fragment {
    private ViewPager2 viewPager;
    private NavigationAdapter navigationAdapter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getActivity().setContentView(R.layout.main_fragment);
        TabLayout tabLayout = getActivity().findViewById(R.id.tabBar);
        int[] tabTexts = {
                R.string.tab_1,
                R.string.tab_2,
                R.string.tab_3
        };

        // set up view pager and attach mediator to tab layout
        this.viewPager = getActivity().findViewById(R.id.pager);
        this.navigationAdapter = new NavigationAdapter(this);
        viewPager.setAdapter(this.navigationAdapter);
        new TabLayoutMediator(tabLayout, viewPager,
                (tab, position) -> tab.setText(
                        tabTexts[position]
                )
        ).attach();
    }
}

NavigationAdapter.java

代码语言:javascript
运行
复制
public class NavigationAdapter extends FragmentStateAdapter {


    public NavigationAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    public NavigationAdapter(@NonNull Fragment fragment) {
        super(fragment);
    }

    public NavigationAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
        super(fragmentManager, lifecycle);
    }


    @NonNull
    @Override
    public Fragment createFragment(int position) {
        switch (position) {
            case 0:
                return new Fragment1();
            case 1:
                return new Fragment2();
            case 2:
                return new Fragment3();

        }
        throw new AssertionError();
    }

    @Override
    public int getItemCount() {
        return 3;
    }
}

nav_graph.xml

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/nav_graph"
    app:startDestination="@id/MainFragment">

    <fragment
        android:id="@+id/MainFragment"
        android:name="com.myapp.fragments.MainFragment"
        android:label="@string/first_fragment_label"
        tools:layout="@layout/main_fragment" />
</navigation>

一切正常,我可以在ViewPager2处理的片段中导航。

然而,只要我将屏幕旋转到其中一个片段中,我就会得到以下信息:

代码语言:javascript
运行
复制
2022-05-08 00:08:12.339 12343-12343/com.myapp E/FragmentManager: Fragment no longer exists for key f#0: unique id c4576c9c-4bbd-4dc0-a304-b86653ed2820
2022-05-08 00:08:12.339 12343-12343/com.myapp E/FragmentManager: Activity state:
2022-05-08 00:08:12.358 12343-12343/com.myapp E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myapp, PID: 12343
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp/com.myapp.MainActivity}: java.lang.IllegalStateException: Fragment no longer exists for key f#0: unique id c4576c9c-4bbd-4dc0-a304-b86653ed2820
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2827)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2902)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4784)
        at android.app.ActivityThread.-wrap18(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:169)
        at android.app.ActivityThread.main(ActivityThread.java:6578)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.IllegalStateException: Fragment no longer exists for key f#0: unique id c4576c9c-4bbd-4dc0-a304-b86653ed2820
        at androidx.fragment.app.FragmentManager.getFragment(FragmentManager.java:975)
        at androidx.viewpager2.adapter.FragmentStateAdapter.restoreState(FragmentStateAdapter.java:549)
        at androidx.viewpager2.widget.ViewPager2.restorePendingState(ViewPager2.java:350)
        at androidx.viewpager2.widget.ViewPager2.dispatchRestoreInstanceState(ViewPager2.java:375)
        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3729)
        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3729)
        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3729)
        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3729)
        at android.view.View.restoreHierarchyState(View.java:17620)
        at com.android.internal.policy.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2130)
        at android.app.Activity.onRestoreInstanceState(Activity.java:1122)
        at android.app.Activity.performRestoreInstanceState(Activity.java:1077)
        at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1260)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2800)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2902) 
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4784) 
        at android.app.ActivityThread.-wrap18(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1609) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:169) 
        at android.app.ActivityThread.main(ActivityThread.java:6578) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

我的装置怎么了?

EN

回答 1

Stack Overflow用户

发布于 2022-10-21 06:57:49

viewpager2脱离回收视图https://issuetracker.google.com/issues/154751401存在一个问题

据我所知,有两个解决办法:

  1. 在xml viewpager2组件中添加这一行。

android:saveEnabled="false">

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72156771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档