我使用过的建议
How to prevent custom views from losing state across screen orientation changes但即使我的View
正确保存了状态,也永远不会调用onRestoreInstanceState
。调用Activity的恢复方法使事情变得更奇怪。
import java.text.DecimalFormat;
import java.text.NumberFormat;
import com.szyk.myheart.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Scroller;
public class NumberScroller extends View implements OnTouchListener{
private final float VIEW_FILL_PERCENTAGE = 80;
private final int MIN_VELOCITY_Y = 100;
private final int VELOCITY_UNIT = 1000;
private final String TAG = "NumberScroller";
private final int ALIGNING_DURATION = 1000;
private boolean isCustomizing = true;
private boolean isDragged = false;
private boolean isNewVelocityTracker = false;
private Scroller scroller;
private VelocityTracker velocityTracker;
private float lastY;
private int absoleteY;
private float velocityY;
private float ascent;
private Integer maxScrollerNumber;
private Integer minScrollerNumber;
private Paint paintNumber;
private Paint paintNumberActivated;
private Paint paintBorder;
private float textOffsetX;
private Drawable foregroundBorder;
private Drawable foregroundAlpha;
private NumberFormat numberFormatter;
/**
* Initializes attributes and variables.
* @param attrs - AttributeSet for Number Scroller
* @param context in which scroller exists.
*/
public NumberScroller(Context context, AttributeSet attrs) {
super(context, attrs);
Log.i(TAG, "Creating NumberScroller.");
initAttrs(attrs, context);
scroller = new Scroller(getContext());
setOnTouchListener(this);
foregroundAlpha = getResources().getDrawable(R.drawable.foreground_alpha);
numberFormatter = new DecimalFormat();
numberFormatter.setMinimumIntegerDigits(maxScrollerNumber.toString()
.length());
numberFormatter.setMinimumFractionDigits(0);
setSaveEnabled(true);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
/**
* (non-Javadoc)
* @see android.view.View#onMeasure(int, int)
*/
/**
* Initializes attributes from xml description.
* @param attrs - AttributeSet for Number Scroller
* @param context in which scroller exists.
*/
private void initAttrs(AttributeSet attrs, Context context) {
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.NumberScroller);
maxScrollerNumber = typedArray.getInteger(
R.styleable.NumberScroller_maximum, 99);
minScrollerNumber = typedArray.getInteger(
R.styleable.NumberScroller_minimum, 0);
if (maxScrollerNumber < minScrollerNumber) {
int tmp = minScrollerNumber;
minScrollerNumber = maxScrollerNumber;
maxScrollerNumber = tmp;
}
typedArray.recycle();
}
V1:
@Override
public Parcelable onSaveInstanceState() {
Log.i(TAG,"SAve");
//begin boilerplate code that allows parent classes to save state
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
//end
ss.stateToSave = absoleteY;
return ss;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
Log.i(TAG,"REstore");
//begin boilerplate code so parent classes can restore state
if(!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState)state;
super.onRestoreInstanceState(ss.getSuperState());
//end
absoleteY = ss.stateToSave;
}
public static class SavedState extends BaseSavedState {
int stateToSave;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.stateToSave = in.readInt();
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(this.stateToSave);
}
//required field that makes Parcelables from a Parcel
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
V2:
@Override
protected Parcelable onSaveInstanceState() {
Log.i(TAG, "Saving state.");
Bundle bundle = new Bundle();
bundle.putParcelable("state", super.onSaveInstanceState());
bundle.putInt("absoleteY", absoleteY);
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
Log.i(TAG, "Restoring state");
if(state instanceof Bundle){
Bundle bundle = (Bundle) state;
absoleteY = bundle.getInt("absoleteY");
super.onRestoreInstanceState(bundle.getParcelable("state"));
return;
}
super.onRestoreInstanceState(state);
}
在日志中,我从未看到“恢复状态”。
看来如果我没有在android.support.v4.view.ViewPager中使用我的自定义视图,则会调用onRestoreInstanceState。有没有人知道原因,我是否必须在活动中调用保存/恢复?
答案 0 :(得分:0)
这个问题已经很老了,但是我在谷歌搜索解决方案时偶然发现了这个问题,然后我发现了它。
问题可能是在根Activity的onCreate方法中以编程方式创建自定义视图。
解决方案是从包含ViewPager的根Activity调用onSaveInstanceState和onRestoreInstanceState,并以编程方式存储自定义视图的状态。
在您的根Activity中实现以下内容:
保存自定义视图的状态
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelable("STATE_COLLECTION", collectionFrameLayout.onSaveInstanceState());
super.onSaveInstanceState(outState);
}
在onCreate()内部,在创建自定义视图后将其恢复。
if (savedInstanceState != null) {
Parcelable state = savedInstanceState.getParcelable("STATE_COLLECTION");
if (state != null) {
collectionFrameLayout.onRestoreInstanceState(state);
}
}