mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Summary: If the z-index was updated after the initial mount, changes would not be reflected because we did not recalculate the z-index mapped child views and redraw the view. This adds code to do that and call it whenever we update z-index. **Test plan** Tested by reproducing the bug with 2 overlapping views that change z-index every second. Made sure it now works properly and z-index changes are reflected. Closes https://github.com/facebook/react-native/pull/15203 Differential Revision: D5564832 Pulled By: achen1 fbshipit-source-id: 5b6c20147211ce0b7e8954d60f8614eafe128fb4
117 lines
3.4 KiB
Java
117 lines
3.4 KiB
Java
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
package com.facebook.react.uimanager;
|
|
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
/**
|
|
* Helper to handle implementing ViewGroups with custom drawing order based on z-index.
|
|
*/
|
|
public class ViewGroupDrawingOrderHelper {
|
|
private final ViewGroup mViewGroup;
|
|
private int mNumberOfChildrenWithZIndex = 0;
|
|
private @Nullable int[] mDrawingOrderIndices;
|
|
|
|
public ViewGroupDrawingOrderHelper(ViewGroup viewGroup) {
|
|
mViewGroup = viewGroup;
|
|
}
|
|
|
|
/**
|
|
* This should be called every time a view is added to the ViewGroup in {@link ViewGroup#addView}.
|
|
* @param view The view that is being added
|
|
*/
|
|
public void handleAddView(View view) {
|
|
if (ViewGroupManager.getViewZIndex(view) != null) {
|
|
mNumberOfChildrenWithZIndex++;
|
|
}
|
|
|
|
mDrawingOrderIndices = null;
|
|
}
|
|
|
|
/**
|
|
* This should be called every time a view is removed from the ViewGroup in {@link ViewGroup#removeView}
|
|
* and {@link ViewGroup#removeViewAt}.
|
|
* @param view The view that is being removed.
|
|
*/
|
|
public void handleRemoveView(View view) {
|
|
if (ViewGroupManager.getViewZIndex(view) != null) {
|
|
mNumberOfChildrenWithZIndex--;
|
|
}
|
|
|
|
mDrawingOrderIndices = null;
|
|
}
|
|
|
|
/**
|
|
* If the ViewGroup should enable drawing order. ViewGroups should call
|
|
* {@link ViewGroup#setChildrenDrawingOrderEnabled} with the value returned from this method when
|
|
* a view is added or removed.
|
|
*/
|
|
public boolean shouldEnableCustomDrawingOrder() {
|
|
return mNumberOfChildrenWithZIndex > 0;
|
|
}
|
|
|
|
/**
|
|
* The index of the child view that should be drawn. This should be used in
|
|
* {@link ViewGroup#getChildDrawingOrder}.
|
|
*/
|
|
public int getChildDrawingOrder(int childCount, int index) {
|
|
if (mDrawingOrderIndices == null) {
|
|
ArrayList<View> viewsToSort = new ArrayList<>();
|
|
for (int i = 0; i < childCount; i++) {
|
|
viewsToSort.add(mViewGroup.getChildAt(i));
|
|
}
|
|
// Sort the views by zIndex
|
|
Collections.sort(viewsToSort, new Comparator<View>() {
|
|
@Override
|
|
public int compare(View view1, View view2) {
|
|
Integer view1ZIndex = ViewGroupManager.getViewZIndex(view1);
|
|
if (view1ZIndex == null) {
|
|
view1ZIndex = 0;
|
|
}
|
|
|
|
Integer view2ZIndex = ViewGroupManager.getViewZIndex(view2);
|
|
if (view2ZIndex == null) {
|
|
view2ZIndex = 0;
|
|
}
|
|
|
|
return view1ZIndex - view2ZIndex;
|
|
}
|
|
});
|
|
|
|
mDrawingOrderIndices = new int[childCount];
|
|
for (int i = 0; i < childCount; i++) {
|
|
View child = viewsToSort.get(i);
|
|
mDrawingOrderIndices[i] = mViewGroup.indexOfChild(child);
|
|
}
|
|
}
|
|
return mDrawingOrderIndices[index];
|
|
}
|
|
|
|
/**
|
|
* Recheck all children for z-index changes.
|
|
*/
|
|
public void update() {
|
|
mNumberOfChildrenWithZIndex = 0;
|
|
for (int i = 0; i < mViewGroup.getChildCount(); i++) {
|
|
if (ViewGroupManager.getViewZIndex(mViewGroup.getChildAt(i)) != null) {
|
|
mNumberOfChildrenWithZIndex++;
|
|
}
|
|
}
|
|
mDrawingOrderIndices = null;
|
|
}
|
|
}
|