Summary:
This changes modal behavior to resize when the keyboard appears/disappears.
Previously, the modal would not react in any way, or it would pan above to bring the
TextInput into view. Resizing is the correct behavior for android.
This is not trivial, as in, setting the flag, because of the combination of
react native laying out all views and the system reacting to the keyboard
appearance in a weird way. Namely:
- if `windowTranslucentStatus` is not set, the system will just call
`onSizeChanged` on the dialog's content view, and everything works nicely
- with `windowTranslucentStatus` set, the system will consider the dialog as a
full screen view that doesn't resize. In order for it to resize, the base
view of the layout needs to have
`setFitsSystemWindows(true)` called on it. This is needed, so that the system
can call layout on that base view with the new value of `paddingBottom` that
coincides with the height of the keyboard. Neat.
We fix this by wrapping our existing content view (mHostView) in a simple
FrameLayout that has `setFitsSystemWindows` set. That way, `mHostView` will have
`onSizeChanged` called on itself with the correct new size of the dialog.
This has the fortunate consequence of our layout now also getting `paddingTop` as the size of the
status bar, which means that we can remove the JS `top` hack in Modal, which
was necessary for no view getting drawn under the status bar.
This behavior is set as default, since that is the default correct Android behavior.
Reviewed By: astreet
Differential Revision: D3913784
fbshipit-source-id: 4378ada21f466dc7ac6e357abeca10b88009ca3f
Summary:
`ReactSwipeRefreshLayout` extends `SwipeRefreshLayout` which does not play nice with Android's touch handling system.
There are two problems:
1. `SwipeRefreshLayout` overrides and swallows `requestDisallowInterceptTouchEvent`, which means that Views underneath the `SwipeRefreshLayout` will not interact correctly with parent Views of
`SwipeRefreshLayout`. We've seen this in practice by H-ScrollViews having their touches intercepted by an enclosing ViewPager. This is fixed by passing `requestDisallowInterceptTouchEvent` up to the parents of `SwipeRefreshLayout`.
2. `SwipeRefreshLayout` overrides `onInterceptTouchEvent` and never calls `super.onInterceptTouchEvent`, therefore ignoring the value of `disallowIntercept`. That means that it will intercept some touches when it
shouldn't. One such case is again the H-ScrollView, which should receive all horizontal scrolls and stop `SwipeRefreshLayout` from intercepting any touch events after scrolling. Currently, after the H-ScrollView starts scrolling, it is still possible to get the `SwipeRefreshLayout` to detect and emit refresh events. This is fixed by checking and blocking on horizontal scrolls.
Reviewed By: foghina
Differential Revision: D3929893
fbshipit-source-id: e6f8050fb554e53318a7ca564c49c20cb5137df9
Summary:
The styles that get applied to the Dialogs that are created in RN are set in
`themes.xml`, so I'm moving `windowTranslucentStatus` there as well so that we
have all of them collocated.
Reviewed By: astreet
Differential Revision: D3913402
fbshipit-source-id: 8f23e84fb017c8810634ffe8279171061292b351
Summary: Create separate buck library for image events so you can depend on that without depending on all of fresco
Reviewed By: brosenfeld
Differential Revision: D3907894
fbshipit-source-id: dca7a00d38b8b8bb5bab05b6883f6933fff3fa76
Summary:
The dialog intercepts all key events, we need to redirect some of them to the
activity so that it can display the dev menu.
Reviewed By: foghina
Differential Revision: D3894503
fbshipit-source-id: fb62346a4da783f28a73c5a9e20566a451177629
Summary:
In some cases, the size of the content view changes before we add views to the
Modal. That means that the size of that view will not be set through the
`onSizeChanged` method. This can result in some apps apparently freezing,
since the dialog is created, but there are no actual views in it.
For that reason, we still need the ModalHostShadowNode to set the size of the
initial view, so that by the time the view gets added it already has the correct
size.
There's a new helper class so that we can reuse the modal size computation.
Reviewed By: foghina
Differential Revision: D3892795
fbshipit-source-id: 6a32bd7680a74d9912a21bfebb4ebd7a3c3c3e38
Summary: Some OEMs have changed out the default scroller implementation in their ScrollView. We now check for that case and handle it gracefully instead of crashing.
Reviewed By: foghina
Differential Revision: D3876492
fbshipit-source-id: 4d03b88c4972e939c8352eeb9f30275e3ecf76e2
Summary:
The issue here is that on some devices (ie. Nexus 5X), under certain
circumstances, the text gets trimmed. A simple example is P56651885, where the
text is at the end of the line and some padding is set. Digging further with
P56659346, I found that only the paddings that have integer pixel values work
correctly: these are the values P56656483, and this is the screenshot of that
test: {F63510378}.
It turns out that when we set the padding directly on the TextView, we have to
convert from float to int, and use `ceil` in the process. We lose some precision
here, since the csslayout will use the float values to compute the layout of the
views. The ideal solution would be to just set the float values on the TextView,
but since we can't do that, we should avoid using `ceil` instead of `floor`
since it can have bad side-effects in some scenarios.
Going way back to D1881202 and D1710471, we started using `ceil` because that
is how android handles non-integer
density ratios: "This figure is the factor by which you should multiply the dp
units on order to get the actual pixel count for the current screen. (Then add
0.5f to round the figure up to the nearest whole number, when converting to an
integer.)", see https://developer.android.com/guide/practices/screens_support.html.
Reviewed By: emilsjolander
Differential Revision: D3876310
fbshipit-source-id: 701c05a8b1a045d4e06fc89ffe79162c1eecb62c
Summary:
With our previous fix to resize the Modal on orientation change, we broke the
computation of its size. The existing computation in `ModalHostShadowNode` was
in fact correct, and we were overriding it from `onSizeChanged`. By computing the
size of the Modal in `onSizeChanged` directly (and correctly), we fix this, and
simplify code by removing the `ModalHostShadowNode`.
Reviewed By: foghina
Differential Revision: D3863054
fbshipit-source-id: aaf4a8881798df4d2ab1dab882a9d9dfdc0a9342
Summary:
This adds support for sticky headers on Android. The implementation if based primarily on the iOS one (https://github.com/facebook/react-native/blob/master/React/Views/RCTScrollView.m#L272) and adds some stuff that was missing to be able to handle z-index, view clipping, view hierarchy optimization and touch handling properly.
Some notable changes:
- Add `ChildDrawingOrderDelegate` interface to allow changing the `ViewGroup` drawing order using `ViewGroup#getChildDrawingOrder`. This is used to change the content view drawing order to make sure headers are drawn over the other cells. Right now I'm only reversing the drawing order as drawing only the header views last added a lot of complexity especially because of view clipping and I don't think it should cause issues.
- Add `collapsableChildren` prop that works like `collapsable` but applies to every child of the view. This is needed to be able to reference sticky headers by their indices otherwise some subviews can get optimized out and break indexes.
Closes https://github.com/facebook/react-native/pull/9456
Differential Revision: D3827366
Pulled By: fred2028
fbshipit-source-id: d346068734c5b987518794ab23e13914ed13b5c4
Summary:
This adds support for sticky headers on Android. The implementation if based primarily on the iOS one (https://github.com/facebook/react-native/blob/master/React/Views/RCTScrollView.m#L272) and adds some stuff that was missing to be able to handle z-index, view clipping, view hierarchy optimization and touch handling properly.
Some notable changes:
- Add `ChildDrawingOrderDelegate` interface to allow changing the `ViewGroup` drawing order using `ViewGroup#getChildDrawingOrder`. This is used to change the content view drawing order to make sure headers are drawn over the other cells. Right now I'm only reversing the drawing order as drawing only the header views last added a lot of complexity especially because of view clipping and I don't think it should cause issues.
- Add `collapsableChildren` prop that works like `collapsable` but applies to every child of the view. This is needed to be able to reference sticky headers by their indices otherwise some subviews can get optimized out and break indexes.
Closes https://github.com/facebook/react-native/pull/9456
Differential Revision: D3827366
fbshipit-source-id: cab044cfdbe2ccb98e1ecd3e02ed3ceaa253eb78
Summary: This is to be able to depend on ReactClippingViewGroup from BaseViewManager. Devs using ReactClippingViewGroup may need to update their imports when updating past this commit.
Reviewed By: lexs
Differential Revision: D3835328
fbshipit-source-id: 290c08b130d837e553b68a90377bd9a30b7ec6dc
Summary:
This automatically changes the size of the modal by listening to dialog size changes and propagating
those changes through UIManager.
In detail: I've looked into three ways of doing this:
1. Send `onSizeChanged` events/info from the View to the CSSNode directly. This is kinda hacky because you would need to hold a reference to the CSSNode somewhere, either in the View or in the ViewManager. But then you'll have to take care of the lifecycle of the CSSNode, so that you don't update it after it has been dismissed. Not great.
2. The version we went for, is to just update the size of the corresponding CSSNode in the same way we do it for root nodes: we inform the UIManager that the size of the root node has changed, and it will propagate that change, triggering a `dispatchViewUpdates` if none is underway, so that the layout is updated.
3. The other solution we thought of is to treat the Modal as a root view. This would mean rendering an application with the tag of the Modal as the root of the application. That tag would be received by calling some method into UIManager and ReactModalHostManager to create a new RootView, create a Dialog and plop the root view in it. The idea was to maintain the JS API that we now have, but make the implementation more correct (ie. since both RootView and the Modal must deal with touch handling), and could have other benefits (ie. no hacks necessary for making the inspector work on top of modals). However, the change is not trivial and I don't know just how much code would have to be changed to make this work correctly. We might revisit this at a later stage, after we've done more work on having several root views at the same time in the app.
Reviewed By: foghina
Differential Revision: D3841379
fbshipit-source-id: f5e363e27041b785cf44eb59da04bc789306ddb9
Summary:
Setting the line height with the help of Android-provided StaticLayout is incorrect. A
simple example app will display the following when `setLineSpacing(50.f, 0.f)`
is set: {F62987699}. You'll notice that the height of the first line is a few
pixels shorter than the other lines.
So we use a custom LineHeightSpan instead, which needs to be applied to the text
itself, and no height-related attributes need to be set on the TextView itself.
Reviewed By: lexs
Differential Revision: D3841658
fbshipit-source-id: 7257df4f1b2ce037554c7a7a5ca8f547a2056939
Summary:
Here's a little background. Resizing is inferior to scaling. See http://frescolib.org/docs/resizing-rotating.html#_
Currently, React Native has a heuristic to use resize when the image is likely to be from the device's camera. However, there may be other cases where a developer wants to use resize. For example, when the developer knows they'll be downloading a large image from a service but the image will be rendered at a small size on the device.
This change adds a `resizeMethod` prop to the `Image` component so developers can choose how Fresco resizes the image. The options are 'auto', 'resize', or 'scale'. When 'auto' is specified, a heuristic is used to choose between 'resize' and 'scale'. The default value is 'auto'.
**Test plan (required)**
In a small test app, verified that the `resizeMethod` prop properly influences the mechanism that is used to resize the image (e.g. resize or scale).
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/9652
Differential Revision: D3841322
Pulled By: foghina
fbshipit-source-id: 6c78b5c75ea73053aa10386afd4cbff45f5b8ffe
Summary:
Currently, `<Text>` and `<TextInput>` components on Android do not support borders.
This change adds support for the borderRadius, borderColor, and
borderWidth props on the `<Text>` and `<TextInput>` components on Android.
ReactViewGroup already implements this functionality so
we copied its implementation over into the ReactTextView
and ReactEditText classes.
**Test plan (required)**
Verified that the various border props work on Text and TextInput components in a test app.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/9658
Differential Revision: D3819993
Pulled By: lexs
fbshipit-source-id: 183b0aa95369dd781f03b5a1f0f409ab47284e39
Summary:
This diff changes the textinput component to only scroll (and interrupt parent
views from scrolling), when it is possible for the text inside the component to
be scrolled. Before (D3735237), we would intercept all touch events on the
textinput if it's focused. But this makes it: a.) impossible to scroll a scrollview from within
a textinput that cannot be scrolled; b.) different from iOS behavior.
What the component now does is intercept move touches, and check if it can
scroll in any direction. If it does, it will intercept the touches and stop the parent
component from scrolling; otherwise, it will give the control back to the parent
component.
Note: this might change in the future to also detect the direction of the scroll, and
only block the scroll if the component can scroll in that direction. This is however not
trivial, since the scroll needs to be above some threshold of pixels. Blocking the
parent view from scrolling until that threshold is passed might cause incorrect behavior
in the parent component.
Reviewed By: astreet
Differential Revision: D3764267
fbshipit-source-id: 47e7b5e03855b3c85789e04fc31a8317afbafa84
Summary:
This fixes some inaccuracies in our reporting of textinput's contentsize.
First, we were not using the correct padding info. Then, we are converting the
contentSize width and height to ints right before sending
them over to JS. This adds some inaccuracy with the textinput behaviour,
especially in the case of auto expending text inputs, since those same sizes are
then sent right back.
Reviewed By: astreet
Differential Revision: D3806008
fbshipit-source-id: 7e32f91fde50099fd8a122833fd0042683e68df1
Summary:
Android PR for TextInput selection, based on the iOS implementation in #8958.
** Test plan **
Tested using the text selection example in UIExplorer.
Closes https://github.com/facebook/react-native/pull/8962
Differential Revision: D3819285
Pulled By: andreicoman11
fbshipit-source-id: 9a2408af2a8b694258c88ab5c46322830c71452a
Summary:
There are a couple of buggy behaviors in the current implementation of the `ellipsizeMode` prop on Android:
- Setting the `numberOfLines` prop stomps on whatever value you provided for `ellipsizeMode` earlier.
- The value you've provided for `ellipsizeMode` is used even if you've configured your view to have an unlimited size (i.e. `numberOfLines` is 0 or unspecified).
This change fixes these issues which makes Android's `ellipsizeMode` prop more consistent with iOS's. Additionally, it renames LineBreakMode to EllipsizeMode in a couple of places.
**Test plan (required)**
Verified that the `numberOfLines` and `ellipsizeMode` props work correctly in an Android test app.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/9594
Differential Revision: D3810166
Pulled By: foghina
fbshipit-source-id: 229c9bfc3ef10670a1090311ea9d095cb2c1121a
Summary:
This is similar to the iOS feature that was implemented by 84f68c338a.
**Test plan (required)**
Verified that the image dimensions are included in the `onLoad` callback in a test app. Also, this change is used in my team's app.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/9608
Differential Revision: D3797659
Pulled By: foghina
fbshipit-source-id: ea83a907bf6b0b61d9bc1e90fc7c64b7132db81f
Summary: Added support for WebViews to take in an onContentSizeChange prop, which will return a native event that contains the width and height of the html content in the WebView. Also moved the ContentSizeChangeEvent from the recyclerview dir to the uimanager/events dir
Reviewed By: andreicoman11
Differential Revision: D3775399
fbshipit-source-id: 19a0579f8345e5853cc7311b80f1f1393c77ab58
Summary:
Setting the line height with the help of Android-provided StaticLayout is incorrect. A
simple example app will display the following when `setLineSpacing(50.f, 0.f)`
is set: {F62987699}. You'll notice that the height of the first line is a few
pixels shorter than the other lines.
So we use a custom LineHeightSpan instead, which needs to be applied to the text
itself, and no height-related attributes need to be set on the TextView itself.
Reviewed By: lexs
Differential Revision: D3751097
fbshipit-source-id: 6c5a8d01a6dca4ff6eef9c3aadd1b550054432d2
Summary:
Setting the line height with the help of Android-provided StaticLayout is incorrect. A
simple example app will display the following when `setLineSpacing(50.f, 0.f)`
is set: {F62987699}. You'll notice that the height of the first line is a few
pixels shorter than the other lines.
So we use a custom LineHeightSpan instead, which needs to be applied to the text
itself, and no height-related attributes need to be set on the TextView itself.
Reviewed By: lexs
Differential Revision: D3751097
fbshipit-source-id: c3574a1080efec26436a5c61afbff89afa8679e7
Summary: Border colors broke with recent change to default values in csslayout Spacing. This is a quick fix until we move react-native borders away from using Spacing.java which is a hack in the first place.
Reviewed By: lexs
Differential Revision: D3735435
fbshipit-source-id: 747c85798cb02e1a5139de038eb26b64ac4c5bf3
Summary:
**Motivation**
For the `Text` component, if `numberOfLines` is set to `0`, the behavior on iOS is such that there is no limit.
On Android, the behavior is such that `numberOfLines={0}` will not render the `Text` component.
Since we want behavior to be the same across platforms, this change will make sure Android behaves the same as iOS.
**Test Plan**
Create a `Text` component specifying `numberOfLines={0}` on an Android project.
Expected:
- `Text` component displays, with no limit to number of lines.
Result:
- `Text` component does not appear at all.
Closes https://github.com/facebook/react-native/pull/9188
Differential Revision: D3697115
fbshipit-source-id: c1768ac22bab3c0e41a9df38b7314f3201512eb2
Summary:
Since the core layout in RN is now assigning `left/right` to `start/end`, we need to tweak the text input handling as well:
1. We need to replace all left/right to start/end
2. For text inset padding, we need to manually flipped the padding in RTL situation.
Reviewed By: fkgozali
Differential Revision: D3670277
fbshipit-source-id: 442bead25af8548a85dd1f359aa5a799982d1185
Summary:
Because it is react, the url could be changed on redirection or some other ways.
The iOS version's WebView has controled that on [here](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m#L106).
But the Android's one is not.
Check the url is same with privous url. If it is true, cancel loading.
This logic is same with iOS's.
the ```method``` hasn't compared.
Test urls as we can.
The Google Map(https://map.google.com) was one of the site which has occur error before this commit.
related issue : #9121
Closes https://github.com/facebook/react-native/pull/9126
Differential Revision: D3663685
Pulled By: javache
fbshipit-source-id: f38c9012ee077677543dafcea83c0778a4471bfa
Summary:
The logic in `setRtl` is wrong. You would expect that `{rtl: true}` would set the layout direction to RTL, instead it currently does the opposite.
This commit fixes the issue.
Closes https://github.com/facebook/react-native/pull/9132
Differential Revision: D3657134
fbshipit-source-id: f946698b548988541de7da5565d2ab122746ecf0
Summary: We now reach in and use the Scroller directly, reimplementing fling() and onOverScrolled(). I verified that in Android 4.1.2 ScrollView#mScroller exists as a private on ScrollView, but there's still potential that this could break things if OEMs have modified ScrollView so we just log a warning if we can't get access to that field.
Reviewed By: foghina
Differential Revision: D3650008
fbshipit-source-id: e52909bf9d6008f6d1ecd458aee25fe82ffaac19
Summary:
Supersedes PR #8536Fixes#5211
JavaScript plugins such as Fotorama are broken when attempting use its fullscreen feature.
If there's an absolute HTML element with 100% height under <body>, its height is 0 when rendered in the Android WebView.
This commit fixes it.
Closes https://github.com/facebook/react-native/pull/8830
Reviewed By: bestander
Differential Revision: D3632821
Pulled By: jamesgpearce
fbshipit-source-id: c185bcd30d1d214a357d0d8552d61d0ddfa5e6c6
Summary: Use UNSET(-1) as default will lead wrong calculation for text alignment. Change it to Gravity.NO_GRAVITY to fix this problem.
Reviewed By: fkgozali
Differential Revision: D3624417
fbshipit-source-id: c116560e64600be60b2fe719f575701b00f20a97
Summary: Change the textalign setter to support RTL. In order to support text alignment according to layout style, move the textalign setter bridge function from ReactTextViewManager.java to ReactTextShadowNode.java and calculate it correctly on RCTTextUpdate.
Reviewed By: dmmiller
Differential Revision: D3597494
fbshipit-source-id: e5ca17b99b4233cc49a447a34175473e339ff53d
Summary:
lineBreakMode only in rc so I think we can replace property without any deprecation warnings. satya164
Closes https://github.com/facebook/react-native/pull/9008
Differential Revision: D3614901
fbshipit-source-id: 724227c0a89192825a24850b930b80884571a51f
Summary:
In Timing.java, the key provided to the remove function of mTimerIdsToTimers is not correct, that may introduce bugs.
Closes https://github.com/facebook/react-native/pull/8966
Differential Revision: D3605291
Pulled By: astreet
fbshipit-source-id: 97563b6846e8f3f40d20b48b3852dd557c9932f3
Summary: This is pure cleanup so that we can make sure that all events are living in the same time space (currently nano seconds).
Reviewed By: foghina
Differential Revision: D3593884
fbshipit-source-id: 71b084362008f1c93c21880630acf11f5c058355
Summary:
This PR was split from a commit originally in #8619. /cc dmmiller
When an inline image was larger than the specified line height,
the image would be clipped. This changes the behavior so
that the line height is changed to make room for the inline
image. This is consistent with the behavior of RN for iOS.
Here's how the change works.
ReactTextView now receives its line height from the layout thread
rather than directly from JavaScript.
The reason is that the layout thread may pick a different line height.
In the case that the tallest inline image is larger than the line
height supplied by JavaScript, we want to use that image's height as
the line height rather than the supplied line height.
Also fixed a bug where the image, which is supposed to be baseline
aligned, would be positioned at the wrong y location. To fix this,
we use `y` (the baseline) in the `draw` method rather than trying
to calculate the baseline from `bottom`. For more information
see https://code.google.com/p/andro
Closes https://github.com/facebook/react-native/pull/8907
Differential Revision: D3592781
Pulled By: dmmiller
fbshipit-source-id: cba6cd86eb4e3abef6a0d7a81f802bdb0958492e