简体   繁体   中英

How to pass a list of custom object through the method View.onSaveInstanceState()?

I have searched the, "custom object passing" issue all over the Internet. There are several solutions but they are all using an Intent to communicate. With Intent, there are methods to facilitate that but what about the method public Parcelable View.onSaveInstanceState()

So, my requirement is saving the state of the view and because it is a custom view, I cannot save the state in the fragment. Rather, I have to override the methods View.onSaveInstanceState() and View.onRestoreInstanceState() .

These methods work with Parcelable . I have a view called, BoxDrawingView and a Box class that is contained inside the view.

One more thing - I have tried to Parcelize the Box class.

import android.graphics.PointF;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Manish Sharma on 9/6/2016.
 */
public class Box implements Parcelable{
    private PointF mOrigin;
    private PointF mCurrent;
    public Box(PointF origin) {
        mOrigin = origin;
        mCurrent = origin;
    }
    public PointF getCurrent() {
        return mCurrent;
    }
    public void setCurrent(PointF current) {
        mCurrent = current;
    }
    public PointF getOrigin() {
        return mOrigin;
    }

    @Override
    public int describeContents() {
        return 0;
    }
    public static final Parcelable.Creator<Box> CREATOR
            = new Parcelable.Creator<Box>() {
        public Box createFromParcel(Parcel in) {
            return new Box(in);
        }

        public Box[] newArray(int size) {
            return new Box[size];
        }
    };
    private Box(Parcel in) {
        mOrigin = (PointF)in.readValue(ClassLoader.getSystemClassLoader());
        mCurrent = (PointF)in.readValue(ClassLoader.getSystemClassLoader());
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeValue(mOrigin);
        out.writeValue(mCurrent);
    }


}

Now, here is the custom view that is supposed to call those 2 lifecycle methods for saving the state:

package com.example.manishsharma.draganddraw;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Manish Sharma on 9/5/2016.
 */
public class BoxDrawingView extends View {
    private static final String TAG = "BoxDrawingView";

private Box mCurrentBox;
private List<Box> mBoxen = new ArrayList<>();
private Paint mBoxPaint;
private Paint mBackgroundPaint;

// Used when creating the view in code
public BoxDrawingView(Context context) {
    this(context, null);
}
// Used when inflating the view from XML
public BoxDrawingView(Context context, AttributeSet attrs) {
    super(context, attrs);

    // Paint the boxes a nice semitransparent red (ARGB)
    mBoxPaint = new Paint();
    mBoxPaint.setColor(0x22ff0000);
    // Paint the background off-white
    mBackgroundPaint = new Paint();
    mBackgroundPaint.setColor(0xfff8efe0);
}

@Override
protected void onDraw(Canvas canvas) {
    // Fill the background
    canvas.drawPaint(mBackgroundPaint);
    for (Box box : mBoxen) {
        float left = Math.min(box.getOrigin().x, box.getCurrent().x);
        float right = Math.max(box.getOrigin().x, box.getCurrent().x);
        float top = Math.min(box.getOrigin().y, box.getCurrent().y);
        float bottom = Math.max(box.getOrigin().y, box.getCurrent().y);
        canvas.drawRect(left, top, right, bottom, mBoxPaint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    PointF current = new PointF(event.getX(), event.getY());
    String action = "";
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            action = "ACTION_DOWN";
            // Reset drawing state
            mCurrentBox = new Box(current);
            mBoxen.add(mCurrentBox);
            break;
        case MotionEvent.ACTION_MOVE:
            action = "ACTION_MOVE";
            if (mCurrentBox != null) {
                mCurrentBox.setCurrent(current);
                invalidate();
            }
            break;
        case MotionEvent.ACTION_UP:
            action = "ACTION_UP";
            mCurrentBox = null;
            break;
        case MotionEvent.ACTION_CANCEL:
            action = "ACTION_CANCEL";
            mCurrentBox = null;
            break;
    }
    Log.i(TAG, action + " at x=" + current.x +
            ", y=" + current.y);
    return true;
}

@Override
public Parcelable onSaveInstanceState(){
    super.onSaveInstanceState();
    //How do I proceed here?
}
}

So finally I have: An arraylist of Parcelable objects that I want to save. How do I do that?

PS: If I use the method Bundle.putParcelableArrayList(String key, ArrayList<? extends Parcelable> value) , it doesn't work because the Box class implements the Parcelable interface not extend it.

save state

@Override
public Parcelable onSaveInstanceState(){
    Parcelable superState = super.onSaveInstanceState();
    Bundle bundle = new Bundle();
    bundle.putParcelable("super", superState);
    bundle.putParcelableArrayList("list", mBoxen);
    return bundle;
}

and restore

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (state instanceof  Bundle) {
        super.onRestoreInstanceState(((Bundle) state).getParcelable("super"));
        mBoxen = ((Bundle) state).getParcelableArrayList("list");
    } else {
        super.onRestoreInstanceState(state);
    }
}

this should work. what is the problem with bundle.putParcelableArrayList("list", mBoxen); ?

I think you should use:

@Override
protected void onSaveInstanceState(Bundle outState) {}

and putExtra into outState bundle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM