question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Missing requestLayout() after setting new margin

See original GitHub issue

As specified in doc, setMargins() requires to call requestLayout after that.

Currently, it works “almost” without it, just on older LG devices (Android 5.1 and 6) views are not updated until I call this manually.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:18 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
killvetrovcommented, Oct 28, 2020

UPDATE: ConstraintLayout 2.0.3 just released https://androidstudio.googleblog.com/2020/10/constraintlayout-203.html It has fixes related to insets handling: https://issuetracker.google.com/issues?q=169262776

Great news is that this release seems to fix this issue! I’ve tried it with example provided by @ChairfaceChippendale and Insetter v0.3.1 and it works flawlessly now.

1reaction
killvetrovcommented, Oct 27, 2020

It’s unfortunate, earlier I believed Insetter was reliable on newer Android versions. In fact, it’s always reliable with padding insets, but not with margins. Indeed your example is reproducible on SDK 29. I’ve spent a few hours debugging this issue and I still can’t figure the clear cause of this problem. Layout inspector shows updated margin on the view, but view position is somehow unaffected until next layout pass. I’ve encountered this in my projects too.

I can think of some possible causes like special treatment of margins in ConstraintLayout and presence of FragmentContainerView, which has additional code for dispatching insets. I feel that Insetter ends up updating layout params somewhere in between of layout pass, which leads to this problem.

Anyway, as the result of my tests I’ve found the following workaround:

View v = view;
while (v.getParent() instanceof View) {
  v = (View) v.getParent();
  v.forceLayout();
}

I added this code after setLayoutParams call https://github.com/chrisbanes/insetter/blob/7a3f0700b1b030c5d47054c833c07755cbb6ccff/library/src/main/java/dev/chrisbanes/insetter/Insetter.java#L444

This forces layout pass of entire view hierarchy to happen on the next frame, when all margins are already updated by Insetter. In theory, requestLayout() has the code to do the same, traversing hierarchy with getParent().requestLayout(), but at the time Insetter calls it getParent().isLayoutRequested() returns true, and condition is not satisfied.

@ChairfaceChippendale the code you commented out with post does mitigate this issue, but produces glitched display. At first views are displayed with incorrect margin, and then jump to correct position after a delay.

You can test my workaround (which doesn’t produce jumps) with JitPack implementation 'com.github.killvetrov:insetter:force-layout-SNAPSHOT'

@chrisbanes I’m sure that greater expertise in view measuring/layout and debugging of ConstraintLayout’s internals should lead to the real cause and a more efficient fix.

Read more comments on GitHub >

github_iconTop Results From Across the Web

android - Change the Right Margin of a View Programmatically?
Basically, you'll want to get the TextView's LayoutParams object, and modify the margins, then set it back to the TextView. Assuming it's in...
Read more >
View - Android Developers
To force focus to a specific view, call requestFocus() . Set up listeners: Views allow clients to set listeners that will be notified...
Read more >
My top margin is missing - Microsoft Support
If your document is in Print Layout view and the top and bottom margins appear to be cut off, the option for hiding...
Read more >
Android how to adjust for soft keyboard | by Yat Man, Wong
But if we have a ConstraintLayout with fixed margin for all… ... mark some views as GONE when detecting the keyboard ... Reset...
Read more >
Java Code Examples for android.view.View#requestLayout()
The following examples show how to use android.view. ... getMeasuredHeight(); Animation a = new Animation() { @Override protected ... GONE); } else {...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found