如何通过View.onSaveInstanceState()方法传递自定义对象列表?

时间:2016-09-07 04:35:03

标签: android parcelable

我在整个互联网上搜索了“自定义对象传递”问题。有几种解决方案,但它们都使用Intent进行通信。使用Intent,有一些方法可以促进这一点,但方法public Parcelable View.onSaveInstanceState()

怎么样

所以,我的要求是保存视图的状态,因为它是一个自定义视图,我无法保存片段中的状态。相反,我必须覆盖方法View.onSaveInstanceState()View.onRestoreInstanceState()

这些方法适用于Parcelable。我有一个名为BoxDrawingView的视图和一个包含在视图中的Box类。

还有一件事 - 我试图将Box类包裹起来。

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);
    }


}

现在,这里是自定义视图,它应该调用这两个生命周期方法来保存状态:

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?
}
}

最后我有:我要保存的Parcelable个对象的arraylist。我该怎么做?

P.S:如果我使用方法Bundle.putParcelableArrayList(String key, ArrayList<? extends Parcelable> value),它不起作用,因为Box类实现了Parcelable接口而不扩展它。

2 个答案:

答案 0 :(得分:0)

保存状态

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

并恢复

@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);
    }
}

这应该有效。 bundle.putParcelableArrayList("list", mBoxen);有什么问题?

答案 1 :(得分:-1)

我认为你应该使用:

@Override
protected void onSaveInstanceState(Bundle outState) {}

并将putExtra放入outState包中。