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

Activity中Fragment屏幕旋转刷新异常问题求助(抽屉布局场景)

Fixing Fragment Refresh Issues on Screen Rotation with DrawerLayout

Hey there, I’ve run into this exact problem multiple times when building apps with DrawerLayout and Fragments—screen rotation causing weird Fragment refresh glitches, duplicate instances, or lost state. Let’s walk through the solutions that consistently work:

1. Stop Re-Adding Fragments on Activity Re-Creation

The biggest culprit here is that Android automatically destroys and recreates your Activity on screen rotation. By default, it also restores the last Fragment instance for you. If you’re still manually adding the default Fragment in onCreate() every time, you’ll end up with duplicate Fragments or state conflicts.

Fix this by checking if savedInstanceState is null before loading your initial Fragment:

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

    // Only load the default Fragment if this is the first launch (not a rotation)
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, new FirstFragment())
            .commit();
    }
}

This way, when the Activity is recreated after rotation, you let the system restore the existing Fragment instead of adding a new one.

2. Properly Save and Restore Fragment State

Even if the Fragment is restored, its UI state (like selected list items, input text, or scroll positions) might get lost. Override onSaveInstanceState() in your Fragments to preserve critical state, then restore it when the Fragment is recreated:

// Inside your Fragment
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    // Save your UI state here (e.g., selected tab position, scroll offset)
    outState.putInt("selected_tab", mSelectedTabIndex);
    outState.putParcelable("scroll_position", mRecyclerView.getLayoutManager().onSaveInstanceState());
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (savedInstanceState != null) {
        // Restore the saved state
        mSelectedTabIndex = savedInstanceState.getInt("selected_tab");
        Parcelable scrollState = savedInstanceState.getParcelable("scroll_position");
        mRecyclerView.getLayoutManager().onRestoreInstanceState(scrollState);
    }
}

This ensures your Fragment’s UI picks up right where it left off after rotation.

3. Use ViewModel for Persistent Data

If your Fragment relies on data that takes time to load (like network responses or database queries), using a ViewModel will keep that data alive through screen rotations. ViewModels aren’t destroyed when the Activity/Fragment is recreated, so you don’t have to re-fetch data every time the screen rotates:

// Create a ViewModel class for your Fragment
public class MyFragmentViewModel extends ViewModel {
    private final MutableLiveData<List<MyData>> mData = new MutableLiveData<>();
    private boolean mIsDataLoaded = false;

    public LiveData<List<MyData>> getData() {
        return mData;
    }

    public void loadData() {
        if (!mIsDataLoaded) {
            // Simulate a network call or database query
            ApiService.fetchData(new Callback<List<MyData>>() {
                @Override
                public void onSuccess(List<MyData> data) {
                    mData.setValue(data);
                    mIsDataLoaded = true;
                }
            });
        }
    }
}

Then in your Fragment:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    MyFragmentViewModel viewModel = new ViewModelProvider(this).get(MyFragmentViewModel.class);
    
    viewModel.getData().observe(getViewLifecycleOwner(), data -> {
        // Update your UI with the data
        updateRecyclerView(data);
    });

    // Load data only if it hasn't been loaded yet
    viewModel.loadData();
}

This eliminates redundant data fetching and keeps your UI consistent across rotations.

4. Optional: Disable Activity Re-Creation (Use With Caution)

If you want to avoid the Activity re-creation entirely, you can add configChanges to your Activity in the AndroidManifest.xml. This tells Android to not destroy the Activity on rotation, and instead call onConfigurationChanged():

<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize">
</activity>

Then handle the layout change manually in your Activity:

@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Re-set the content view to load the landscape/portrait layout
    setContentView(R.layout.activity_main);
    
    // Update your current Fragment's UI if needed
    Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
    if (currentFragment != null) {
        ((ConfigurableFragment) currentFragment).onConfigurationChanged(newConfig);
    }
}

Note: This approach requires more manual work to handle layout changes and state sync, so only use it if the first three solutions don’t fit your use case.


内容的提问来源于stack exchange,提问作者Farrukh khalid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:56:02