diff --git a/android/src/main/java/com/facebook/yoga/android/YogaLayout.java b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java index 14591736..cf734df0 100644 --- a/android/src/main/java/com/facebook/yoga/android/YogaLayout.java +++ b/android/src/main/java/com/facebook/yoga/android/YogaLayout.java @@ -231,6 +231,28 @@ public class YogaLayout extends ViewGroup { super.removeAllViewsInLayout(); } + /** + * Marks a particular view as "dirty" and to be relaid out. If the view is not a child of this + * {@link YogaLayout}, the entire tree is traversed to find it. + * + * @param view the view to mark as dirty + */ + public void invalidate(View view) { + if (mYogaNodes.containsKey(view)) { + mYogaNodes.get(view).dirty(); + return; + } + + final int childCount = mYogaNode.getChildCount(); + for (int i = 0; i < childCount; i++) { + final YogaNode yogaNode = mYogaNode.getChildAt(i); + if (yogaNode.getData() instanceof YogaLayout) { + ((YogaLayout) yogaNode.getData()).invalidate(view); + } + } + invalidate(); + } + private void removeViewFromYogaTree(View view, boolean inLayout) { final YogaNode node = mYogaNodes.get(view); if (node == null) { @@ -293,9 +315,7 @@ public class YogaLayout extends ViewGroup { protected void onLayout(boolean changed, int l, int t, int r, int b) { // Either we are a root of a tree, or this function is called by our parent's onLayout, in which // case our r-l and b-t are the size of our node. - if (!(getParent() instanceof YogaLayout) && - Math.round(mYogaNode.getLayoutHeight()) != b-t && - Math.round(mYogaNode.getLayoutWidth()) != r-l) { + if (!(getParent() instanceof YogaLayout)) { createLayout( MeasureSpec.makeMeasureSpec(r - l, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(b - t, MeasureSpec.EXACTLY)); diff --git a/docs/_docs/api/android.md b/docs/_docs/api/android.md index 8b42f671..d2a7340d 100644 --- a/docs/_docs/api/android.md +++ b/docs/_docs/api/android.md @@ -30,3 +30,9 @@ The list of all attributes can be found in [attrs.xml](https://github.com/facebo ## Auto margins You can specify `margin_left="auto"` (or `margin_right` etc.) for auto values. This is in addition to the dimensions you can speicfy, such as `margin_left="20dp"`. + +## Invalidation (_temporary_) + +If you change any attribute of a view that will change its measure size, you must invalidate it. Do this by calling `YogaLayout#invalidate(View)` on any `YogaLayout` further up the tree. Obviously it is most efficient to call it on the view's parent (if it is a `YogaLayout`, but in case this is impractical, you can call it on the root of the tree. + +This is a temporary solution. Ideally, the view should invalidate itself whenever an attribute (text, font etc.) that will alter its size changes. This will be automatic once we find a good way to hook into the Android invalidation system.