Android屏幕旋转后,如何恢复自定义ArrayList<PuzzlePiece>的状态?
Got it, let's work through this problem step by step. The core issues here are that your PuzzlePiece class isn't set up to be serialized for state saving, and you're using the wrong method to store your ArrayList. Here's how to fix it properly:
PuzzlePiece implement Parcelable Android can only save custom objects that implement the Parcelable interface (it's the efficient Android-specific way to serialize objects). Update your PuzzlePiece class to include this implementation—don't forget to save the parent AppCompatImageView state too:
public class PuzzlePiece extends android.support.v7.widget.AppCompatImageView implements Parcelable { public int xCoord; public int yCoord; public int pieceWidth; public int pieceHeight; public boolean canMove = true; public PuzzlePiece(Context context) { super(context); } // Parcelable constructor to rebuild the object from a Parcel protected PuzzlePiece(Parcel in) { super(in); // Critical: Saves the ImageView's internal state (drawable, visibility, etc.) xCoord = in.readInt(); yCoord = in.readInt(); pieceWidth = in.readInt(); pieceHeight = in.readInt(); canMove = in.readByte() != 0; // Convert byte back to boolean } // Required Parcelable creator public static final Creator<PuzzlePiece> CREATOR = new Creator<PuzzlePiece>() { @Override public PuzzlePiece createFromParcel(Parcel in) { return new PuzzlePiece(in); } @Override public PuzzlePiece[] newArray(int size) { return new PuzzlePiece[size]; } }; @Override public int describeContents() { return 0; // Return 0—we don't have special objects like file descriptors to flag } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); // Save parent View state first dest.writeInt(xCoord); dest.writeInt(yCoord); dest.writeInt(pieceWidth); dest.writeInt(pieceHeight); dest.writeByte((byte) (canMove ? 1 : 0)); // Convert boolean to byte for Parcel } }
onSaveInstanceState Instead of putParcelableArray, use putParcelableArrayList—it's designed specifically for storing ArrayLists of Parcelable objects. Update your state saving method:
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelableArrayList("saved_pieces", pieces); }
You can restore the state either in onCreate or onRestoreInstanceState—both work, pick whichever fits your code flow better:
Option 1: Restore in onCreate
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); if (savedInstanceState != null) { // Retrieve the saved list pieces = savedInstanceState.getParcelableArrayList("saved_pieces"); // Reattach the PuzzlePiece views to your layout and update their positions here } else { // Initialize a new list if there's no saved state pieces = new ArrayList<>(); // ... your initial puzzle setup code } }
Option 2: Restore in onRestoreInstanceState
@Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); pieces = savedInstanceState.getParcelableArrayList("saved_pieces"); // Refresh your UI with the restored puzzle pieces here }
- If you add non-primitive fields to
PuzzlePiecelater (like custom drawable wrappers), make sure those also implementParcelable. - After restoring, you'll need to re-add the
PuzzlePieceviews to your parent layout (since Android recreates the view hierarchy on rotation) and reapply their positions using the savedxCoord/yCoordvalues.
内容的提问来源于stack exchange,提问作者MarkAlanFrank

