开发者

Saving and restoring non-Parcelable UI state for a dumb widget

开发者 https://www.devze.com 2022-12-17 09:02 出处:网络
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 som

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号