Saving and restoring non-Parcelable UI state for a dumb widget
I have a "dumb" custom Android widget (as in View
, not a home screen widget) that I need to have retain some state during screen rotations. This PlayerWidget
is essentially a media player UI with some buttons (back, forward, play/pause) and a progress bar. It exposes the important bits of UI via getters.
There are a few separate Activities
, each of which has a specialised controller object — these use the getters to update whether the buttons should be enabled, or have a "play" or a "pause" icon, and updates the progress bar as it receives callbacks from a background Service
.
For example, in one controller's "start playing" method, it does this:
mWidget.getMiddleButton().setImageResource(R.drawable.btn_pause);
There's an Activity
where screen rotation is handled via onConfigurationChanged
— this calls setContentView()
(because the layout differs between portrait and landscape), and binds the newly-created PlayerWidget
to the still-existing controller object.
That works fine: progress updates start to ha开发者_开发技巧ppen on the new widget instance and the buttons work as expected.
However, the buttons do not have the correct icons because the PlayerWidget
— not having knowledge of its controller — does not know how it is being used and thus what it should be displaying.
I was wondering whether the best idea would be to write getState
and restoreState
methods that the parent Activity
can call before and after the new setContentView()
, however I have no way of parceling a Drawable
from the ImageButtons
— or is there?
Or I considered wrapping the ImageButton
objects which the PlayerWidget
getters return, so that I can save (and thus later restore) the Drawable
resource ID that the controller sets.
Alternatively, when I bind a new PlayerWidget
to the controller, the controller could have some sort of "set-widget-UI-state-based-on-current-controller-state" method? That's potentially complex for various reasons, but feels like the "right" way of doing it.
Any input on this slightly rambling problem would be appreciated! :)
It's a bit of hack but you could store the resource IDs of the drawables in your widget. So on your widget have some code like:
private int mMiddleButtonImage;
public void setMiddleButtonImage(int resourceId) {
mMiddleButtonImage = resourceId;
getMiddleButton().setImageResource(resourceId);
}
The getState()
and restoreState()
method could then use the integer resource IDs rather than the drawables themselves.
For completion, I ended up using the "set-widget-UI-state-based-on-current-controller-state" approach, which was simpler than I thought.
精彩评论