Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add zIndex support #7825

Conversation

tuckerconnelly
Copy link
Contributor

@tuckerconnelly tuckerconnelly commented May 29, 2016

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.

ios activityindicator

android activityindicator

ios image

android image

android picker

ios picker

ios pickerios

ios scrollview

android scrollview

android view

ios view

ios slider

android slider

ios switch

android switch

ios text

android text

ios textinput

android textinput

android webview

screen shot 2016-05-29 at 7 01 38 pm

iOS seems to have a bug where zPosition is ignored when calling renderInContext (http://lists.apple.com/archives/cocoa-dev/2013/Jan/msg00084.html), so the test snapshots won't be z-indexed. If it's important enough I can look into another solution besides using zPosition.


iOS WebView was tough. Apparently RCTWebView is a subview? I set the zPosition on the superview in webViewDidFinishLoad, which seems a little hacky to me, so maybe someone can suggest a better solution :)

@ghost
Copy link

ghost commented May 29, 2016

By analyzing the blame information on this pull request, we identified @mkonicek and @bestander to be potential reviewers.

@ghost ghost added GH Review: review-needed CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. labels May 29, 2016
@ghost
Copy link

ghost commented May 29, 2016

@tuckerconnelly updated the pull request.

commonStyles,
{marginLeft: 150, backgroundColor: '#64B5F6', zIndex: -1}
]}>
<Text>ZIndex -1</Text>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing something, but shouldn't a view with zIndex = -1 appear underneath a view view with zIndex = 0? In testViewExample_1@2x.png, it's on top.

@nicklockwood
Copy link
Contributor

This looks promising, but I think the implementation on iOS needs to work by sorting the actual view order instead of adjusting the layer.zPosition.

(I also think you may have got the sign wrong on the zPosition anyway, as it appears that views with higher zIndex are being drawn behind views with lower zIndex, whereas according to the CSS spec "An element with greater stack order is always in front of an element with a lower stack order.")

@tuckerconnelly
Copy link
Contributor Author

Nick, in the comment above:

iOS seems to have a bug where zPosition is ignored when calling renderInContext (http://lists.apple.com/archives/cocoa-dev/2013/Jan/msg00084.html), so the test snapshots won't be z-indexed.

Doesn't matter though 'cause zPosition won't work :P. Would bringSubviewToFront work?

Also, for Android, will bringToFront work with touch events?

@nicklockwood
Copy link
Contributor

iOS seems to have a bug where zPosition is ignored when calling renderInContext

Ah, that makes sense.

Doesn't matter though 'cause zPosition won't work :P. Would bringSubviewToFront work?

Yes, but we need to be very careful when messing with the view order so that subsequent updates don't end up removing the wrong view.

I think we need to figure out the best place to do the view sorting. Options are:

  1. In the view itself, inside the setReactSubviews method. That will mean storing the reactSubviews in an array and then sorting the views when they are added to the underlying UIView.subviews array.

  2. In the UIManager, so that views are sorted prior to being inserted into the view/shadowView

  3. On the JS side, so that they are already sorted by zIndex before they are sent over the bridge.

I'm not sure which of these is the best option, although 3) has the nice benefit that we could share the code between iOS and Android and avoid platform-specific hacks.

Also, for Android, will bringToFront work with touch events?

Sorry, I don't know anything about Android ¯_(ツ)_/¯

@nicklockwood
Copy link
Contributor

Now I think about it, 3) probably isn't viable since it will affect the flexbox layout if we change the order prior to sending the views to native.

That means the order of shadowViews can't be changed based on zIndex, we can only change the order for UIViews.

@tuckerconnelly
Copy link
Contributor Author

UIManager seems like the simplest to me--if it was done in the setReactSubviews method I think it'd have to be done in all the components' setReactSubviews methods. I'll give it a shot :)

@nicklockwood
Copy link
Contributor

@tuckerconnelly I've got an idea how to approach this using setReactSubviews actually. I'll let you know if I can make it work.

@nicklockwood
Copy link
Contributor

@tuckerconnelly I have a solution working for iOS. I'm just checking that it doesn't negatively affect performance.

ghost pushed a commit that referenced this pull request Jun 7, 2016
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See #7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from #7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
@nicklockwood
Copy link
Contributor

@tuckerconnelly OK, I've landed zIndex support for iOS: d64368b

You should be able to rebase your PR on top to add Android support.

@nicklockwood
Copy link
Contributor

Cc: @dmmiller Dave, can you review the Android implementation here? I don't know the platform well enough to judge if this is an appropriate solution, or if we need to implement something like what I've done on iOS.

@tuckerconnelly
Copy link
Contributor Author

DUDE YEAH! I can tomorrow

@syzer
Copy link

syzer commented Jun 7, 2016

👍

@dmmiller
Copy link

dmmiller commented Jun 9, 2016

Is this on every single view or are some exempted for some reason? In general, the core seems correct. I'm a little sad about doing this with an interface and 10 copy/pasted lines in every single view. This also won't scale if we have views that are purely native and not wrapped by react native. Is there a way to maybe do this with an annotation on the view (that addresses the first part, but not the second)?

@tuckerconnelly
Copy link
Contributor Author

tuckerconnelly commented Jun 9, 2016

Yeah I didn't like the interface either. I can't really imagine a way to do it with annotations without stepping out of ViewManager-manages-View pattern, but I'm not a pro with Java :)

What if we created a generic View and have every subclass of View contain a reference to the android component. So something like:

public class ReactGenericView<T extends android.view.View> {
  private @Nullable float mZIndex;

  public void setZIndex(float zIndex) {
    mZIndex = zIndex;
  }

  public float getZIndex() {
    return mZIndex;
  }
  // Other future props
  // Could also put borderRadius, etc. in here
  public abstract T getComponent()
}

class ReactImageView extends ReactGenericView<GenericDraweeView> {
  // Stuff specific to Images
  @Override
  public GenericDraweeView getComponent() {
    // return lazily-initialized GenericDraweeView
  }
}

class ReactImageManager {
  @ReactProp(name = "tintColor", customType = "Color")
  public void setTintColor(ReactImageView view, @Nullable Integer tintColor) {
    if (tintColor == null) {
      view.getComponent().clearColorFilter();
    } else {
      view.getComponent().setColorFilter(tintColor, Mode.SRC_IN);
    }
  }
}

That's a pretty big change though.

Re: purely native views, I could put a default in to treat them as zIndex: 0, and if they wanted to set their own zIndex, they could implement the interface (or extend GenericView) and React would pick up on it.

Edit: Actually that wouldn't work with the interface because it wouldn't re-order the siblings when set. It would work with GenericView though, if the siblings were re-ordered on setZIndex.

@dmmiller
Copy link

dmmiller commented Jun 9, 2016

@lexs do you know a good way to do this with annotations?

@@ -116,6 +122,15 @@ public void invalidateDrawable(Drawable drawable) {
super.invalidateDrawable(drawable);
}

public void setZIndex(float targetZIndex) {
zIndex = targetZIndex;
ViewGroupManager.reorderChildrenByZIndex((ViewGroup) this.getParent());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this special?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, that's old. I'll delete it.

@lexs
Copy link
Contributor

lexs commented Jun 9, 2016

We talked about the Android side internally and have a few wishes.

Instead of forcing each view to implement an interface can we have a look-aside map like: WeakHashMap<View, Integer>. Note that this will also require changing both impls to use int instead of float. The reason to use Integer here is that we can avoid boxing (and instead relying on the internal Java cache for small Integers), there is no such cache for floats. Using integers is also the css spec: https://developer.mozilla.org/en/docs/Web/CSS/z-index

We'd also like to move to a model where addChild() doesn't require sorting children if none of them have a z-index because we're afraid this might hurt perf. As I'd really like to see this land I don't think we need to do it in this PR but we (you or us internally) should look into this in the future depending on how inefficient the current implementation is. We have a few ideas on how to do this by for example keeping track of which ViewGroups contain z-indexed children and skipping sorting if we know they contain no z-children.

@nicklockwood
Copy link
Contributor

We'd also like to move to a model where addChild() doesn't require sorting children if none of them have a z-index because we're afraid this might hurt perf

FWIW, the iOS implementation has this optimisation. I currently do it in a fairly naive way – instead of keeping track as the views are added, I just do a single pass through the views to see if any has a non-zero zIndex before I sort them – but that means the common case is O(n) instead of O(n log n) so it still seems worth doing.

@mkonicek
Copy link
Contributor

@tuckerconnelly,@lexs What's the status? Does this need review or changes?

@dmmiller
Copy link

It needs to be rebased and updated.

@tuckerconnelly
Copy link
Contributor Author

Alright it's up. I also added the optimization to check if there are any non-zero z-indexes before sorting 😃

@lexs
Copy link
Contributor

lexs commented Jun 23, 2016

@tuckerconnelly Thanks, I'll import this now and test it internally for perf regressions. I'll merge it on Monday if everything goes well :)

@lexs
Copy link
Contributor

lexs commented Jun 23, 2016

@facebook-github-bot import

@ghost
Copy link

ghost commented Jun 23, 2016

Thanks for importing. If you are an FB employee go to Phabricator to review.

rozele pushed a commit to microsoft/react-native-windows that referenced this pull request Jun 28, 2016
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See facebook/react-native#7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from facebook/react-native#7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
@lexs
Copy link
Contributor

lexs commented Jun 29, 2016

@facebook-github-bot shipit

1 similar comment
@lexs
Copy link
Contributor

lexs commented Jun 29, 2016

@facebook-github-bot shipit

@ghost ghost added the Import Started This pull request has been imported. This does not imply the PR has been approved. label Jun 29, 2016
@ghost
Copy link

ghost commented Jun 29, 2016

Thanks for importing. If you are an FB employee go to Phabricator to review.

@ghost ghost closed this in 3d3b067 Jun 29, 2016
@bestander
Copy link
Contributor

I am a bit confused about the changed images for the iOS snapshot tests.
How are they related to the java change?

@bestander
Copy link
Contributor

@lexs, the test was failing on the CI for the PR https://travis-ci.org/facebook/react-native/builds/137840201, be careful :)

bestander added a commit to bestander/react-native that referenced this pull request Jun 30, 2016
Tests got broken after facebook#7825, reverting changes

Test Plan:
./scritps/objc-test.sh
ghost pushed a commit that referenced this pull request Jun 30, 2016
Summary:
Tests got broken after #7825, reverting changes
Closes #8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa
@tuckerconnelly
Copy link
Contributor Author

Picked the wrong yours/theirs in my revert/rebase. Had a hard time getting the Snapshot Test Cases to run again so just ignored it :P I can try to get them fixed up tomorrow morning

@bestander
Copy link
Contributor

No worries, fixd it now bb0fda7

rozele pushed a commit to microsoft/react-native-windows that referenced this pull request Jul 6, 2016
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 facebook/react-native#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658
rozele pushed a commit to microsoft/react-native-windows that referenced this pull request Jul 6, 2016
Summary:
Tests got broken after facebook/react-native#7825, reverting changes
Closes facebook/react-native#8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa
samerce pushed a commit to iodine/react-native that referenced this pull request Aug 23, 2016
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See facebook#7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from facebook#7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
samerce pushed a commit to iodine/react-native that referenced this pull request Aug 23, 2016
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 facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658
samerce pushed a commit to iodine/react-native that referenced this pull request Aug 23, 2016
Summary:
Tests got broken after facebook#7825, reverting changes
Closes facebook#8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa
mpretty-cyro pushed a commit to HomePass/react-native that referenced this pull request Aug 25, 2016
Summary:
This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons:

1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them.
2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable.

See facebook#7825 for further discussion of this problem.

So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself.

It works as follows:

1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager.
2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of  `reactSubviews` by zIndex) and inserts the result into the view.
3.  If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and  `didUpdateReactSubviews` is called again.

To demonstrate it working, I've modified the UIExplorer example from facebook#7825

Reviewed By: javache

Differential Revision: D3365717

fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
mpretty-cyro pushed a commit to HomePass/react-native that referenced this pull request Aug 25, 2016
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 facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658
mpretty-cyro pushed a commit to HomePass/react-native that referenced this pull request Aug 25, 2016
Summary:
Tests got broken after facebook#7825, reverting changes
Closes facebook#8508

Differential Revision: D3503439

Pulled By: bestander

fbshipit-source-id: 95b9283371654265234d975e1b0df540f4ef55fa
berrytj pushed a commit to mdcollab/react-native that referenced this pull request Nov 8, 2016
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 facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658
berrytj pushed a commit to mdcollab/react-native that referenced this pull request Jan 22, 2017
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 facebook#7825

Differential Revision: D3469374

Pulled By: lexs

fbshipit-source-id: b2b74b71d968ebf73ecfd457ace3f35f8f7c7658
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Import Started This pull request has been imported. This does not imply the PR has been approved.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants