如何在扩展 ImageView 的类上保存状态?

Posted

技术标签:

【中文标题】如何在扩展 ImageView 的类上保存状态?【英文标题】:How to save state on a class which extends ImageView? 【发布时间】:2015-08-20 00:36:37 【问题描述】:

我有一个骰子类(游戏是 Greed 或 Farkle),它实现了 ImageView。

package se.mobilapplikationer.greeddicegame.model;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

import java.util.Random;

/**
 * Class representing a single die
 */
public class Die extends ImageView implements View.OnClickListener, Parcelable 

    //The value of the die
    private int value;
    //Random value generator
    private final Random random = new Random();
    //Is the die stored?
    private boolean stored;// = false;
    //Is the die locked?
    private boolean locked;// = true;
    //Main context
    private final Context context;

    Drawable drawable;

    @Override
    public int describeContents() 
        return 0;
    

    @Override
    public void writeToParcel(Parcel dest, int flags) 
        dest.writeInt(value);
        dest.writeByte((byte) (stored ? 1 : 0));
        dest.writeByte((byte) (locked ? 1 : 0));
    

    public Die(Context context) 
        super(context);
        this.context = context;
    

    public Die(Context context, AttributeSet attrs) 
        super(context, attrs);
        this.context = context;
        init(context);

    

    public Die(Context context, AttributeSet attrs, int defStyle) 
        super(context, attrs, defStyle);
        this.context = context;
        init(context);

    

    /**
     * Sets the die image to nan and adds click listener.
     *
     * @param context
     */
    private void init(Context context) 
        setOnClickListener(this);
        setImageResource(context.getResources().getIdentifier("nan", "drawable", context.getPackageName()));
    

    /**
     * Throw the die, generating a value from 1 to 6
     */
    public void throwDie() 
        this.value = random.nextInt((6 - 1) + 1) + 1;
        updateImage();
    

    /**
     * Update the image to its corresponding value
     */
    private void updateImage() 
        setImageResource(context.getResources().getIdentifier("white" + value, "drawable", context.getPackageName()));
    


    @Override
    public void onClick(View v) 
        //Dont do anything if the die is locked.
        if (locked) 
            return;
        
        //If the die is only stored, unstore it.
        if (stored) 
            unStore();
         else 
            store();
        

    


    private void store() 
        setImageResource(context.getResources().getIdentifier("grey" + value, "drawable", context.getPackageName()));
        this.stored = true;
    

    private void unStore() 
        setImageResource(context.getResources().getIdentifier("white" + value, "drawable", context.getPackageName()));
        this.stored = false;
    

    /**
     * Lock the die, setting the die image to red
     */
    public void lock() 
        setImageResource(context.getResources().getIdentifier("red" + value, "drawable", context.getPackageName()));
        this.locked = true;

    

    /**
     *
     * @return stored condition of the die
     */
    public boolean isStored() 
        return stored;
    

    /**
     *
     * @return Locked condition of the die
     */
    public boolean isLocked() 
        return locked;
    

    /**
     *
     * @return The value of the die
     */
    public int getValue() 
        return value;
    

    /**
     * Reset the die, locking it, unstoring it and setting image to nan
     */
    public void reset() 
        this.value = 0;
        this.locked = true;
        this.stored = false;
        setImageResource(context.getResources().getIdentifier("nan", "drawable", context.getPackageName()));
    

    /**
     * Unlocks the die
     */
    public void unlock() 
        this.locked = false;
    




现在我在屏幕旋转时遇到问题,类没有被保存,因为我不知道如何使用 parcelable 正确保存这个类,因为我无法创建类似的方法。

public Die(Parcel in)
    ....

有人知道怎么做,或者有解决方法吗?

【问题讨论】:

【参考方案1】:

视图本身没有被打包;您要保存的状态已打包。它应该看起来像这样:

static class SavedState extends View.BaseSavedState 
    int example; // things you want to save

    SavedState(Parcel superState) 
        super(superState);
    

    private SavedState(Parcel in) 
        super(in);
        this.example = in.readInt();
    

    @Override
    public void writeToParcel(Parcel out, int flags) 
        out.writeInt(example);
    

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


@Override
public Parcelable onSaveInstanceState() 
    final Parcelable superState = super.onSaveInstanceState();
    SavedState ss = new SavedState(superState);
    ss.example = ...;
    return ss;


@Override 
public void onRestoreInstanceState(Parcelable state) 
    SavedState ss = (SavedState) state;
    super.onRestoreInstanceState(ss.getSuperState());
    doSomething(ss.example);

【讨论】:

以上是关于如何在扩展 ImageView 的类上保存状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JQuery 中添加的类上执行 .click()?

二进制 XML 文件第 13 行:在扩展 VideoView 的类上膨胀类时出错

如何在已经扩展 Thread 的类中扩展 JFrame

在从STAThread实例调用的类上创建Thread时,公寓状态是什么?

保存当前 ImageView 状态以关闭和重新打开应用程序

Scala:尝试了扩展方法,但无法完全构造(多个类上的扩展名相同)