1

我已使用 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被调用。有谁知道这个原因,我必须从活动内部调用save/restore吗?

+0

请张贴一些代码。 –

+0

“onRestoreInstanceState”根本没有被调用,或者你的'View'的前一个状态没有被恢复?另外,由于vizier已经评论过,你应该添加自定义视图的代码。 – Luksprog

回答

0

这个问题很古老,但当我找出解决方案后,我偶然发现了这个问题。

问题可能是自定义视图是在根Activity的onCreate方法内以编程方式创建的。

解决方法是从包含ViewPager的根Activity调用onSaveInstanceState和onRestoreInstanceState,并以编程方式存储自定义视图的状态。

内,您的根系活力具有如下功能:

保存自定义视图

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