android - FrameLayout child view not updating correctly on resize -
i have android application in root view framelayout
on rotation kept , resized rather recreated.
among children of frameview
1 custom view
(the main view) takes entire space, , custom view
want display narrow band along bottom edge (in portrait mode) or right edge (in landscape mode).
to end run following code main view's onsizechanged()
method:
boolean isbandshowing = ...; // whether band should shown boolean isportrait = ...; // whether in portrait mode, controls band displayed int horizontalbandheight = ...; // default height band in portrait mode int verticalbandwidth = ...; // default width band in landscape mode bandview.setvisibility(isbandshowing ? view.visible : view.gone); layoutparams bandlayoutparams = new framelayout.layoutparams( isportrait ? layoutparams.match_parent : verticalbandwidth, // x isportrait ? horizontalbandheight : layoutparams.match_parent, // y gravity.bottom | gravity.right); bandview.setlayoutparams(bandlayoutparams);
upon creation, onsizechanged()
gets called once (visible in log output) , sets band supposed to.
when display rotated, however, position of band not updated properly. after first rotation portrait landscape, band still displays @ bottom. when rotate portrait, band moves right – consistently lagging behind.
adding log output, can see following:
onsizechanged()
gets called on every rotation- the 4 variables @ top have correct value (portrait/landscape correctly reflects new orientation)
- if query width , height newly created
layoutparams
, have expected values - if query dimensions of
bandview
right after callsetlayoutparams()
, have old values (as displayed before rotation).
i've tried few things, no avail:
- calling
requestlayout()
on bothframelayout
, band view - calling
invalidate()
on both - calling
postinvalidate()
on both - removing
bandview
framelayout
before setting newlayoutparams
, re-adding it
what gives?
as had suspected based on log output, in guts of ui has not been updated time onsizechanged()
gets called. haven't figured out what, takeaway layoutparams
stuff needs deferred until else has finished. can done wrapping code runnable
, post()
ing framelayout
:
static boolean isbandshowing = ...; // whether band should shown static boolean isportrait = ...; // whether in portrait mode, controls band displayed static int horizontalbandheight = ...; // default height band in portrait mode static int verticalbandwidth = ...; // default width band in landscape mode framelayout.post(new runnable() { @override public void run() { bandview.setvisibility(isbandshowing ? view.visible : view.gone); layoutparams bandlayoutparams = new framelayout.layoutparams( isportrait ? layoutparams.match_parent : verticalbandwidth, // x isportrait ? horizontalbandheight : layoutparams.match_parent, // y gravity.bottom | gravity.right); bandview.setlayoutparams(bandlayoutparams); } });
that solved it.
Comments
Post a Comment