From 91cccbe436995979da706c9a7ab66cd6f6941183 Mon Sep 17 00:00:00 2001 From: Richard Zadorozny Date: Thu, 2 Jul 2020 08:37:44 -0700 Subject: [PATCH] Sonar tag for skipping empty view groups in layout target mode Summary: I think it's somewhat common to have large containers that can hold future views, especially fragments. The problem is the presence of these containers can block the layout inspector's "target" mode. I found out from cekkaewnumchai that Flipper does in fact return multiple results from the pick, but I think it could still be helpful to have this new tag since it is more convenient than having to do the secondary drill down each time. Reviewed By: jknoxville Differential Revision: D22284972 fbshipit-source-id: 1a2826ec746e4f31690db33ed72815ae168bffab --- .../descriptors/ViewGroupDescriptor.java | 27 ++++++++++++++++--- android/src/main/res/values/ids.xml | 1 + docs/setup/layout-plugin.mdx | 9 +++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/ViewGroupDescriptor.java b/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/ViewGroupDescriptor.java index 89fc27bb4..3c1042176 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/ViewGroupDescriptor.java +++ b/android/src/main/java/com/facebook/flipper/plugins/inspector/descriptors/ViewGroupDescriptor.java @@ -294,12 +294,31 @@ public class ViewGroupDescriptor extends NodeDescriptor { } private static boolean shouldSkip(View view) { - Object tag = view.getTag(R.id.flipper_skip_view_traversal); - if (!(tag instanceof Boolean)) { - return false; + if (hasTag(view, R.id.flipper_skip_view_traversal)) { + return true; } - return (Boolean) tag; + if (view instanceof ViewGroup + && hasTag(view, R.id.flipper_skip_empty_view_group_traversal) + && !hasVisibleChildren((ViewGroup) view)) { + return true; + } + + return false; + } + + private static boolean hasTag(View view, int id) { + Object tag = view.getTag(id); + return tag instanceof Boolean && (Boolean) tag; + } + + private static boolean hasVisibleChildren(ViewGroup viewGroup) { + for (int i = 0; i < viewGroup.getChildCount(); i++) { + if (viewGroup.getChildAt(i).getVisibility() == View.VISIBLE) { + return true; + } + } + return false; } @Override diff --git a/android/src/main/res/values/ids.xml b/android/src/main/res/values/ids.xml index bb4488b57..156cf5207 100644 --- a/android/src/main/res/values/ids.xml +++ b/android/src/main/res/values/ids.xml @@ -8,4 +8,5 @@ + diff --git a/docs/setup/layout-plugin.mdx b/docs/setup/layout-plugin.mdx index 482b91f8d..4a3714594 100644 --- a/docs/setup/layout-plugin.mdx +++ b/docs/setup/layout-plugin.mdx @@ -66,6 +66,15 @@ Add the following tag to your view to skip it from Flipper's view picker. The vi view.setTag(R.id.flipper_skip_view_traversal, true); ``` +### Blocking empty view groups (Android only) + +If you have a ViewGroup that only occasionally has visible children, you may find it helpful to block its traversal when it is empty or has no visible children. For example, you might have a FragmentContainerView that currently has no visible fragment. + +Add the following tag to your view group to skip it from Flipper's view picker only when it has zero children, or none of its children are currently visible. The views will still be shown in the layout hierarchy, but they will not be selected while using the view picker. + +```java +viewGroup.setTag(R.id.flipper_skip_empty_view_group_traversal, true); +``` ## iOS