【问题标题】:Android Custom view save and restore state [duplicate]Android自定义视图保存和恢复状态[重复]
【发布时间】:2016-03-17 22:33:40
【问题描述】:

我有自定义组件扩展 ImageView。方法 onSaveInstanceState 和 onRestoreInstanceState 工作正常,但不幸的是当我单击视图时 mIsSelectedState = false

我该如何解决这个问题?

public class CustomImageView extends ImageView {

private boolean mIsSelectedState;
...

public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs, defStyleAttr);
}

private void init(Context context, AttributeSet attrs, int defStyleAttr) {
    setSaveEnabled(true);

    TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyleAttr, 0);
    ...
    attributes.recycle();

    mPaintImage = new Paint(Paint.ANTI_ALIAS_FLAG);
    ...
}

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (!isClickable()) {
        mIsSelectedState = false;
        return super.onTouchEvent(event);
    }

    ...

    invalidate();
    return super.dispatchTouchEvent(event);
}

...

@Override
protected Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();
    SavedState savedState = new SavedState(superState);

    savedState.mSelected = mIsSelectedState;
    return savedState;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if(!(state instanceof SavedState)) {
        super.onRestoreInstanceState(state);
        return;
    }

    SavedState savedState = (SavedState)state;
    super.onRestoreInstanceState(savedState.getSuperState());
    setSelectedState(savedState.mSelected);
    setBorderColor(mBorderSelectedColor);
}

private void setSelectedState(boolean isSelected) {
    mIsSelectedState = isSelected;
}

...

private static class SavedState extends BaseSavedState {
    boolean mSelected;

    SavedState(Parcelable superState) {
        super(superState);
    }

    private SavedState(Parcel in) {
        super(in);
        mSelected = in.readByte() != 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        super.writeToParcel(out, flags);
        out.writeByte((byte) (mSelected ? 1 : 0));
    }

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

【问题讨论】:

  • 可能会进入 if (!isClickable()) { mIsSelectedState = false;这就是为什么你把它弄错了。你调试了吗?
  • 仅供参考:在我看来,没有必要创建自己的包裹。在大多数情况下,它会给你的代码添加一堆杂乱无章的东西。只需使用内置的 Bundle 类,并在其上设置属性。
  • @ShadabAnsari 是的,我检查过了。我还对其进行了更详细的调试。在 onDraw() 调用 onRestoreInstantState 并将 mIsSelectedState 设置为正确值之前,但不幸的是在 onDraw() 期间我的数据不正确
  • @Matt 为什么你认为 Bundle 更好?作为视图中的示例 super.onSaveInstanceState() 返回 Parcelabble 对象。当我们谈论作为示例 Activity 时,我同意你的看法。
  • 主要是因为你不能搞砸包裹上的包裹。自定义包裹总是有可能被错误编码。

标签: android android-view android-custom-view


【解决方案1】:

saveStates的正确做法如下:

首先覆盖onSaveInstanceState()

 @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.puBoolean("myconstantKey", mIsSelectedState);
    }

然后,无论何时恢复它,您都应该覆盖:

 @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    // Restore state members from saved instance
    mIsSelectedState = savedInstanceState.getInt("myconstantKey");
}

您也可以在 onCreate 上进行操作,以防您在活动之间切换

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {
           mIsSelectedState = savedInstanceState.getBoolean("myconstantKey");
        }

        ...
    }

记住 Android Activity 生命周期很棘手,但一旦掌握了窍门,一切都会变得更好 :)

希望对你有帮助。

【讨论】:

  • 这是活动的正确方式,但我认为他想在视图级别处理它。
  • 是的,我想在视图级别保存和恢复数据
猜你喜欢
  • 2017-01-04
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
相关资源
最近更新 更多