mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Improve z-index implementation on Android
Summary: Use `getChildDrawingOrder` instead of reordering views. The old implementation didn't work properly when `removeClippedSubviews` was enabled and this one should have better performance since we don't play with the view hierarchy at all. This fixes weird bugs with sticky headers in `SectionList` and allows removing the hack that disabled `removeClippedSubviews` when using sticky section headers. **Test plan** Tested using the SectionList and ListViewPaging examples that use sticky headers which uses z-index. Closes https://github.com/facebook/react-native/pull/13105 Reviewed By: sahrens Differential Revision: D4765869 Pulled By: achen1 fbshipit-source-id: be3c824658a3ce965b6e7324ad95c77cbd8a86ae
This commit is contained in:
1 parent
af533ac7f1
commit
9a51fa8e15
7 files changed
+149
-53
No files matched your search
@@ -19,13 +19,15 @@ import java.util.WeakHashMap;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Class providing children management API for view managers of classes extending ViewGroup.
|
||||
*/
|
||||
public abstract class ViewGroupManager <T extends ViewGroup>
|
||||
extends BaseViewManager<T, LayoutShadowNode> {
|
||||
|
||||
public static WeakHashMap<View, Integer> mZIndexHash = new WeakHashMap<>();
|
||||
private static WeakHashMap<View, Integer> mZIndexHash = new WeakHashMap<>();
|
||||
|
||||
@Override
|
||||
public LayoutShadowNode createShadowNodeInstance() {
|
||||
@@ -43,7 +45,6 @@ public abstract class ViewGroupManager <T extends ViewGroup>
|
||||
|
||||
public void addView(T parent, View child, int index) {
|
||||
parent.addView(child, index);
|
||||
reorderChildrenByZIndex(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,54 +62,10 @@ public abstract class ViewGroupManager <T extends ViewGroup>
|
||||
|
||||
public static void setViewZIndex(View view, int zIndex) {
|
||||
mZIndexHash.put(view, zIndex);
|
||||
// zIndex prop gets set BEFORE the view is added, so parent may be null.
|
||||
ViewGroup parent = (ViewGroup) view.getParent();
|
||||
if (parent != null) {
|
||||
reorderChildrenByZIndex(parent);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reorderChildrenByZIndex(ViewGroup view) {
|
||||
// Optimization: loop through the zIndexHash to test if there are any non-zero zIndexes
|
||||
// If there aren't any, we can just return out
|
||||
Collection<Integer> zIndexes = mZIndexHash.values();
|
||||
boolean containsZIndexedElement = false;
|
||||
for (Integer zIndex : zIndexes) {
|
||||
if (zIndex != 0) {
|
||||
containsZIndexedElement = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!containsZIndexedElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add all children to a sortable ArrayList
|
||||
ArrayList<View> viewsToSort = new ArrayList<>();
|
||||
for (int i = 0; i < view.getChildCount(); i++) {
|
||||
viewsToSort.add(view.getChildAt(i));
|
||||
}
|
||||
// Sort the views by zIndex
|
||||
Collections.sort(viewsToSort, new Comparator<View>() {
|
||||
@Override
|
||||
public int compare(View view1, View view2) {
|
||||
Integer view1ZIndex = mZIndexHash.get(view1);
|
||||
if (view1ZIndex == null) {
|
||||
view1ZIndex = 0;
|
||||
}
|
||||
|
||||
Integer view2ZIndex = mZIndexHash.get(view2);
|
||||
if (view2ZIndex == null) {
|
||||
view2ZIndex = 0;
|
||||
}
|
||||
return view1ZIndex - view2ZIndex;
|
||||
}
|
||||
});
|
||||
// Call .bringToFront on the sorted list of views
|
||||
for (int i = 0; i < viewsToSort.size(); i++) {
|
||||
viewsToSort.get(i).bringToFront();
|
||||
}
|
||||
view.invalidate();
|
||||
public static @Nullable Integer getViewZIndex(View view) {
|
||||
return mZIndexHash.get(view);
|
||||
}
|
||||
|
||||
public int getChildCount(T parent) {
|
||||
|
||||
Reference in new issue
Block a user