Add zIndex support
Summary: Adds zIndex support :) **Test Plan** Tested the following components by adding two of each, overlapping them, and setting a high zIndex on the first of the two: ActivityIndicator Image MapView Picker ScrollView Slider Switch Text TextInput View WebView Tested on Android 4.1 and iOS 8.4. Also tested updating zIndexes on Views in my own app. <img width="359" alt="ios activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633473/88f842cc-257b-11e6-8539-c41c0b179f80.png"> <img width="330" alt="android activityindicator" src="https://cloud.githubusercontent.com/assets/4349082/15633475/88f95784-257b-11e6-80c0-2bf3ed836503.png"> <img width="357" alt="ios image" src="https://cloud.githubusercontent.com/assets/4349082/15633474/88f93d80-257b-11e6-9e54-4ff8e4d25f71.png"> <img width="340" alt="android image" src="https://cloud.githubusercontent.com/assets/4349082/15633478/88fd2788-257b-11e6-8c80-29078e65e808.png"> <img width="342" alt="android picker" src="ht Closes https://github.com/facebook/react-native/pull/7825 Differential Revision: D3469374 Pulled By: lexs fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658
This commit is contained in:
parent
3085b35e63
commit
3d3b067f6f
Binary file not shown.
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 128 KiB |
Binary file not shown.
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 153 KiB |
|
@ -93,7 +93,7 @@ var ZIndexExample = React.createClass({
|
|||
flipped: false
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
render() {
|
||||
const indices = this.state.flipped ? [-1, 0, 1, 2] : [2, 1, 0, -1];
|
||||
return (
|
||||
|
@ -128,7 +128,7 @@ var ZIndexExample = React.createClass({
|
|||
</TouchableWithoutFeedback>
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
_handlePress() {
|
||||
this.setState({flipped: !this.state.flipped});
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ package com.facebook.react.uimanager;
|
|||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
@ -21,6 +22,7 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|||
private static final String PROP_TRANSFORM = "transform";
|
||||
private static final String PROP_OPACITY = "opacity";
|
||||
private static final String PROP_ELEVATION = "elevation";
|
||||
private static final String PROP_Z_INDEX = "zIndex";
|
||||
private static final String PROP_RENDER_TO_HARDWARE_TEXTURE = "renderToHardwareTextureAndroid";
|
||||
private static final String PROP_ACCESSIBILITY_LABEL = "accessibilityLabel";
|
||||
private static final String PROP_ACCESSIBILITY_COMPONENT_TYPE = "accessibilityComponentType";
|
||||
|
@ -70,6 +72,12 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
|||
// Do nothing on API < 21
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_Z_INDEX)
|
||||
public void setZIndex(T view, float zIndex) {
|
||||
int integerZIndex = Math.round(zIndex);
|
||||
ViewGroupManager.setViewZIndex(view, integerZIndex);
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_RENDER_TO_HARDWARE_TEXTURE)
|
||||
public void setRenderToHardwareTexture(T view, boolean useHWTexture) {
|
||||
view.setLayerType(useHWTexture ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE, null);
|
||||
|
|
|
@ -12,12 +12,20 @@ package com.facebook.react.uimanager;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* 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<>();
|
||||
|
||||
@Override
|
||||
public LayoutShadowNode createShadowNodeInstance() {
|
||||
return new LayoutShadowNode();
|
||||
|
@ -34,6 +42,59 @@ public abstract class ViewGroupManager <T extends ViewGroup>
|
|||
|
||||
public void addView(T parent, View child, int index) {
|
||||
parent.addView(child, index);
|
||||
reorderChildrenByZIndex(parent);
|
||||
}
|
||||
|
||||
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 int getChildCount(T parent) {
|
||||
|
|
|
@ -195,6 +195,7 @@ public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
|
|||
} else {
|
||||
parent.addView(child, index);
|
||||
}
|
||||
reorderChildrenByZIndex(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue