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

如何在onSaveInstanceState中保存Fragment的自定义类状态

Got it, let's fix this state loss issue step by step. The problem right now is that when a configuration change (like screen rotation) happens, your fragment gets recreated, and since you're not saving the log data and other state variables, everything resets. Here's how to fix it:


Step 1: Make LogItems Serializable

First, your LogItems class needs to implement the Serializable interface so it can be stored in a Bundle. This is required because we need to save the entire list of log entries, and each entry must be serializable to be written to the bundle.

Update your LogItems code:

package com.example.student.mysterygame;

import java.io.Serializable;

public class LogItems implements Serializable { // Add the Serializable interface
    private String logName;
    private String logDate;
    private String logEntry;

    public String getLogName(){return logName;}
    public String getLogDate(){return logDate;}
    public String getLogEntry(){return logEntry;}

    public void setLogName(String LogName){this.logName = LogName;}
    public void setLogDate(String LogDate){this.logDate = LogDate;}
    public void setLogEntry(String logEntry){this.logEntry = logEntry;}

    public LogItems(String name, String date, String logEntry){
        this.logEntry = logEntry;
        this.logName = name;
        this.logDate = date;
    }
}

Step 2: Fix Dangerous Static Members & Activity Initialization

Using static variables like mArrayList and mArrayAdapter is a big red flag here—it can cause memory leaks and unexpected behavior when the fragment is recreated. Let's convert them to instance variables:

// Remove the static keywords from these members in your logView fragment
public ArrayAdapter<LogItems> mArrayAdapter;
public ArrayList<LogItems> mArrayList;

// Keep other instance variables as-is
AbsListView mListView;
EditText testField;
String mmMessage;
String name;
String date;
boolean hasEnteredPassword;
private MainActivity mmActivity;

Also, fix the mmActivity initialization—never create a new Activity instance with new MainActivity(). Instead, cast the fragment's attached activity to your MainActivity type:

// Replace mmActivity = new MainActivity(); with this line in onViewCreated
mmActivity = (MainActivity) getActivity();

Step 3: Implement onSaveInstanceState to Save State

Now we'll store all critical state data into the Bundle that's preserved across configuration changes:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    // Save the full list of log entries
    savedInstanceState.putSerializable("LOG_ITEMS", mArrayList);
    // Save the password entry state
    savedInstanceState.putBoolean("HAS_ENTERED_PASSWORD", hasEnteredPassword);
    // Optional: Save the current text in the edit field
    savedInstanceState.putString("EDIT_TEXT_CONTENT", testField.getText().toString());
}

Step 4: Restore State When the Fragment Recreated

We need to pull the saved data back out when the fragment is rebuilt. Do this in the onCreate method to initialize your list and adapter correctly:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Check if we have saved state to restore
    if (savedInstanceState != null) {
        // Restore the log items list
        mArrayList = (ArrayList<LogItems>) savedInstanceState.getSerializable("LOG_ITEMS");
        // Restore the password entry state
        hasEnteredPassword = savedInstanceState.getBoolean("HAS_ENTERED_PASSWORD");
    } else {
        // Initialize empty list if this is the first creation
        mArrayList = new ArrayList<LogItems>();
    }
    // Create the adapter with the (restored or new) list
    mArrayAdapter = new textLogAdpater(getActivity(), mArrayList);
}

Also, restore the edit text content in onViewCreated:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // ... existing code to find views ...
    testField = getView().findViewById(R.id.editText);
    
    // Restore edit text content if available
    if (savedInstanceState != null) {
        String savedText = savedInstanceState.getString("EDIT_TEXT_CONTENT");
        testField.setText(savedText);
    }
    // ... rest of your existing code ...
}

Bonus: Fix Duplicate Initial Log Entries

Right now, your initial log messages (like "Connecting to Friend1 Phone....") are added every time onViewCreated runs—including after a configuration change, leading to duplicates. Fix this by only running that code on the fragment's first creation:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    // ... existing code ...

    /**
     * ALL POPULATION REQUESTS FOR THE LOG SHOULD BE PUT BELOW THIS COMMENT.
     */
    if (savedInstanceState == null) { // Only run on first creation
        Log.d("Log Population", "OnCreate called for LogPopulation");
        populateLogOnStartWith("UI", "10/11/2018:", "Connecting to Friend1 Phone....");
        populateLogOnStartWith("UI", "10/11/2018:", "Phone is now Connected");
        populateLogOnStartWith("UI", "10/123/2018:", "Enter Password to access phone:");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:31:53