Android Fragment切换后视图状态无法持久化的问题求助
Hey there! I totally get why this is frustrating—you tweak your ImageView's state, switch away from the fragment, and when you come back it’s like nothing ever changed. Let’s break down why this happens and how to fix it for good.
Why Does This Reset Happen?
When you navigate away from a fragment, the Android system might destroy the fragment’s view hierarchy (to save memory, even if the fragment instance itself sticks around). When you return, onCreateView() runs again, inflating a fresh copy of your layout—resetting all views to their original XML-defined state. That’s why your ImageView pops back to visible and enabled.
Solution 1: Use ViewModel (Recommended)
ViewModel is built exactly for this scenario—it stores data that survives view destruction and fragment recreation. Here’s how to implement it:
First, create a ViewModel class to hold your state:
import androidx.lifecycle.ViewModel; public class GraphStateViewModel extends ViewModel { // Default state: ImageView is visible and enabled private boolean isPowerGraphVisible = true; public boolean isPowerGraphVisible() { return isPowerGraphVisible; } public void setPowerGraphVisible(boolean visible) { isPowerGraphVisible = visible; } }
Then update your Fragment to use this ViewModel:
public class YourMainFragment extends Fragment { private GraphStateViewModel viewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Initialize the ViewModel—it persists across view recreations viewModel = new ViewModelProvider(this).get(GraphStateViewModel.class); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.your_fragment_layout, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ImageView powerGraph = view.findViewById(R.id.PowerGraphEmpty); Button testBtn = view.findViewById(R.id.btntest); // Restore the saved state when the view loads if (!viewModel.isPowerGraphVisible()) { powerGraph.setVisibility(View.GONE); powerGraph.setEnabled(false); } // Update state and save it to ViewModel when the button is clicked testBtn.setOnClickListener(v -> { powerGraph.setVisibility(View.GONE); powerGraph.setEnabled(false); viewModel.setPowerGraphVisible(false); }); } }
Solution 2: Use SavedInstanceState
If you only need to preserve state temporarily (like during screen rotation or system-initiated fragment destruction), use onSaveInstanceState():
public class YourMainFragment extends Fragment { private static final String KEY_GRAPH_VISIBLE = "graph_visible_state"; private boolean isPowerGraphVisible = true; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Restore state if it exists from a previous instance if (savedInstanceState != null) { isPowerGraphVisible = savedInstanceState.getBoolean(KEY_GRAPH_VISIBLE, true); } } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.your_fragment_layout, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ImageView powerGraph = view.findViewById(R.id.PowerGraphEmpty); Button testBtn = view.findViewById(R.id.btntest); // Apply the saved state to the view if (!isPowerGraphVisible) { powerGraph.setVisibility(View.GONE); powerGraph.setEnabled(false); } testBtn.setOnClickListener(v -> { powerGraph.setVisibility(View.GONE); powerGraph.setEnabled(false); isPowerGraphVisible = false; }); } // Save state before the fragment's view is destroyed @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(KEY_GRAPH_VISIBLE, isPowerGraphVisible); } }
Which Solution to Choose?
- ViewModel: Ideal for long-term state persistence (even if the fragment is fully destroyed and recreated, like when navigating back from another screen or after app backgrounding).
- SavedInstanceState: Better for temporary state that only needs to survive system-triggered events (not reliable for keeping state when users navigate away and return normally).
Pro Tip
Avoid using fragment instance variables or global variables to save view state—these get reset when the fragment is destroyed, so they won’t solve your problem.
内容的提问来源于stack exchange,提问作者Amin Kadkhodaee

