You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

旋转屏幕后TabLayout状态无法持久化的问题排查

屏幕旋转后ViewPager2+TabLayout无法恢复选中Tab的问题

问题描述

尝试通过onSaveInstanceState()保存当前Tab位置,屏幕旋转后currentTabPosition的数值是正确的,但执行以下代码无法切换到对应Tab:

viewPager2.post(() -> {        
    viewPager2.setCurrentItem(currentTabPosition, false);
    tabLayout.getTabAt(currentTabPosition);
});

手动指定具体数值(比如1)时能正常切换到对应Tab。

问题代码

ConfigureFragment代码

public class ConfigureFragment extends Fragment {

    private TabLayout tabLayout;
    private ViewPager2  viewPager2;
    private ConfigureViewPageAdapter configureViewPageAdapter;

    private int currentTabPosition = 0; // Track the current selected tab position
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View fragmentView = inflater.inflate(R.layout.fragment_configure, container, false);

       tabLayout = fragmentView.findViewById(R.id.tabLayoutInConfigure);
       viewPager2 = fragmentView.findViewById(R.id.viewPagerInConfigure);

       configureViewPageAdapter = new ConfigureViewPageAdapter(requireActivity());

       viewPager2.setAdapter(configureViewPageAdapter);

       String[] titles = new String[]{"Activity","Sensors"};

       new TabLayoutMediator(tabLayout,viewPager2,((tab, position) -> {tab.setText(titles[position]);})).attach();

        if(savedInstanceState!=null){
            currentTabPosition = savedInstanceState.getInt("currentTabPosition");
            Log.d("ADDD",currentTabPosition+"inside");
        }

        Log.d("ADDD",currentTabPosition+"Outside");

        viewPager2.post(() -> {
            viewPager2.setCurrentItem(currentTabPosition, false);
            tabLayout.getTabAt(currentTabPosition);
        });

        // Inflate the layout for this fragment
        return fragmentView;
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save the current selected tab position
        outState.putInt("currentTabPosition", tabLayout.getSelectedTabPosition());
    }

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

}

ConfigureViewPageAdapter代码

package com.hasanur.realtimehar.Adapter;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import com.hasanur.realtimehar.ActivityConfigureFragment;
import com.hasanur.realtimehar.SensorConfigureFragment;

import java.util.ArrayList;

public class ConfigureViewPageAdapter extends FragmentStateAdapter {

    private ArrayList<Fragment> fragmentArrayList = new ArrayList<Fragment>();

    public ConfigureViewPageAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
        add(new ActivityConfigureFragment());
        add(new SensorConfigureFragment());
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragmentArrayList.get(position);
    }

    @Override
    public int getItemCount() {
        return fragmentArrayList.size();
    }

    public void add(Fragment fragment){
        fragmentArrayList.add(fragment);
    }
}

解决方案

原因分析

  1. TabLayoutMediator在ViewPager2设置适配器后会自动同步初始状态,此时还未恢复保存的Tab位置,后续调用setCurrentItem可能被Mediator的默认同步覆盖。
  2. tabLayout.getTabAt(currentTabPosition)仅获取Tab对象,没有执行选中操作,属于无效代码。

修复步骤

  1. 将恢复Tab位置的逻辑移到onViewStateRestored方法中,该方法是专门用于恢复视图状态的回调,执行时机晚于onCreateView,能确保ViewPager2和TabLayout完全初始化。
  2. 移除无效的tabLayout.getTabAt调用,ViewPager2.setCurrentItem执行后,TabLayoutMediator会自动同步Tab的选中状态。

修改后的ConfigureFragment代码

public class ConfigureFragment extends Fragment {

    private TabLayout tabLayout;
    private ViewPager2  viewPager2;
    private ConfigureViewPageAdapter configureViewPageAdapter;

    private int currentTabPosition = 0; // Track the current selected tab position
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View fragmentView = inflater.inflate(R.layout.fragment_configure, container, false);

       tabLayout = fragmentView.findViewById(R.id.tabLayoutInConfigure);
       viewPager2 = fragmentView.findViewById(R.id.viewPagerInConfigure);

       configureViewPageAdapter = new ConfigureViewPageAdapter(requireActivity());

       viewPager2.setAdapter(configureViewPageAdapter);

       String[] titles = new String[]{"Activity","Sensors"};

       new TabLayoutMediator(tabLayout,viewPager2,((tab, position) -> {tab.setText(titles[position]);})).attach();

        if(savedInstanceState!=null){
            currentTabPosition = savedInstanceState.getInt("currentTabPosition");
            Log.d("ADDD",currentTabPosition+"inside");
        }

        Log.d("ADDD",currentTabPosition+"Outside");

        // Inflate the layout for this fragment
        return fragmentView;
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save the current selected tab position
        outState.putInt("currentTabPosition", tabLayout.getSelectedTabPosition());
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        // 在此处恢复Tab位置,确保视图与Mediator初始化完成
        if(savedInstanceState!=null){
            currentTabPosition = savedInstanceState.getInt("currentTabPosition");
            viewPager2.setCurrentItem(currentTabPosition, false);
        }
    }

}

额外优化

若仍存在问题,可添加ViewPager2页面变化监听,实时同步currentTabPosition,确保保存的位置准确:

// 在onCreateView中添加
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
    @Override
    public void onPageSelected(int position) {
        super.onPageSelected(position);
        currentTabPosition = position;
    }
});

内容的提问来源于stack exchange,提问作者Hasan Seam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:50:34