Android 自定义/复合控件:可共享状态是共享的,但不应该共享?
我在 Android 应用程序中创建了一个自定义视图/复合控件,它允许用户“绘制”他们的签名。
签名包含在画布中,链接到位图对象。
我希望在方向改变时保留签名“图像”。因此,我通过存储位图的像素来实现 onSaveInstanceState / onRestoreInstanceState:
@Override
public Parcelable onSaveInstanceState()
{
// Call superclass method, retrieve Parcelable
Parcelable superState = super.onSaveInstanceState();
if (pictureBitmap_ != null)
{
// Retrieve the current pixels array.
int totalSize = pictureBitmap_.getWidth()
* pictureBitmap_.getHeight();
int pixels[] = new int[totalSize];
pictureBitmap_.getPixels(pixels,
0,
pictureBitmap_.getWidth(),
0,
0,
pictureBitmap_.getWidth(),
pictureBitmap_.getHeight());
// Create the saved state object.
SavedState savedState = new SavedState(superState);
savedState.pixels = pixels;
// Return the populated saved state object.
return savedState;
}
else
{
// Simply pass original Parcelable along
return superState;
}
}
@Override
public void onRestoreInstanceState(Parcelable state)
{
// Is the Parcelable an instance of our custom SavedState?
if (!(state instanceof SavedState))
{
// No, simply delegate to superclass.
super.onRestoreInstanceState(state);
return;
}
// Retrieve custom state object.
SavedState savedState = (SavedState) state;
// Use superclass to restore original state.
super.onRestoreInstanceState(savedState.getSuperState());
// Restore custom state (transfer pixels).
this.transferPixels_ = savedState.pixels;
// If the picture bitmap is already initialized...
if (pictureBitmap_ != null)
{
// Transfer the pixels right away.
transferBitmap();
// Refresh the canvas
drawSignature();
}
}
像素的整数数组存储在 SavedState 对象中,该对象是 BaseSavedState 的自定义子类:
private static class SavedState
extends BaseSavedState
{
// Members
int[] pixels;
// Methods
SavedState(Parcelable superState)
{
super(superState);
}
private SavedState(Parcel in)
{
super(in);
in.readIntArray(pixels);
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeIntArray(pixels);
}
// required field that makes Parcelables from a Parcel
@SuppressWarnings("unused")
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];
}
};
}
现在,如果我只有一 (1) 个实例,则此方法运行良好我的活动中的自定义视图...如果我有两 (2) 个或更多实例,则会出现问题:当我翻转方向时,我的所有控件最终都会显示相同的签名,这是最后一个控件的签名。
换句话说,存储在 SavedState 对象中的最后一组像素似乎成为我的 Activity 中所有控件实例的“通用”像素组。
如何确保每个控件都有自己独立的保存状态?
I have created a custom View / Compound Control in my Android application, which lets users "draw" their signature.
The signature is contained in a Canvas, linked to a Bitmap object.
I want the signature "image" to be preserved when the orientation is changed. Therefore, I have implemented onSaveInstanceState / onRestoreInstanceState by storing the Bitmap's pixels:
@Override
public Parcelable onSaveInstanceState()
{
// Call superclass method, retrieve Parcelable
Parcelable superState = super.onSaveInstanceState();
if (pictureBitmap_ != null)
{
// Retrieve the current pixels array.
int totalSize = pictureBitmap_.getWidth()
* pictureBitmap_.getHeight();
int pixels[] = new int[totalSize];
pictureBitmap_.getPixels(pixels,
0,
pictureBitmap_.getWidth(),
0,
0,
pictureBitmap_.getWidth(),
pictureBitmap_.getHeight());
// Create the saved state object.
SavedState savedState = new SavedState(superState);
savedState.pixels = pixels;
// Return the populated saved state object.
return savedState;
}
else
{
// Simply pass original Parcelable along
return superState;
}
}
@Override
public void onRestoreInstanceState(Parcelable state)
{
// Is the Parcelable an instance of our custom SavedState?
if (!(state instanceof SavedState))
{
// No, simply delegate to superclass.
super.onRestoreInstanceState(state);
return;
}
// Retrieve custom state object.
SavedState savedState = (SavedState) state;
// Use superclass to restore original state.
super.onRestoreInstanceState(savedState.getSuperState());
// Restore custom state (transfer pixels).
this.transferPixels_ = savedState.pixels;
// If the picture bitmap is already initialized...
if (pictureBitmap_ != null)
{
// Transfer the pixels right away.
transferBitmap();
// Refresh the canvas
drawSignature();
}
}
The integer array of pixels is stored in a SavedState object, which is a custom subclass of BaseSavedState:
private static class SavedState
extends BaseSavedState
{
// Members
int[] pixels;
// Methods
SavedState(Parcelable superState)
{
super(superState);
}
private SavedState(Parcel in)
{
super(in);
in.readIntArray(pixels);
}
@Override
public void writeToParcel(Parcel out, int flags)
{
super.writeToParcel(out, flags);
out.writeIntArray(pixels);
}
// required field that makes Parcelables from a Parcel
@SuppressWarnings("unused")
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];
}
};
}
Now, while this is working well if I only have ONE (1) instance of my custom view in my activity... a problem occurs if I have TWO (2) or more instances: when I flip the orientation, all my controls end up displaying the same signature, which was the last control's signature.
In other words, the last set of pixels stored in a SavedState object appears to become the "universal" set of pixels for all my control instances within my Activity.
How do I ensure that each control has its own independent saved state?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论