Closed minhthong095 closed 2 months ago
Can you run react-native info
and edit your issue to include these results under the Environment section?
If you believe this information is irrelevant to the reported issue, you may write [skip envinfo]
under Environment to let us know.
I am closing this issue because it does not contain the necessary environment info, and there has been no followup in a while.
If you found this thread after encountering the same issue in the latest release, please feel free to create a new issue with up-to-date information by clicking here.
Anyone? I believe it's a bug.
I have the same problem. This has been tested both on Expo and a standalone React Native app, both in appetize emulator and on a Xiaomi Pocophone F1. Same behavior, no horizontal nested scrolling on Android, but works great on iOS
Code here https://snack.expo.io/@esbenvb/scrollview-tests
Android behavior https://vimeo.com/322265966
iOS behavior https://vimeo.com/322266040
React Native Environment Info:
System:
OS: macOS 10.14.3
CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
Memory: 331.47 MB / 16.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.12.0 - /usr/local/bin/node
Yarn: 1.10.1 - /usr/local/bin/yarn
npm: 6.4.1 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
Android SDK:
API Levels: 23, 25, 26, 27, 28
Build Tools: 26.0.2, 26.0.3, 27.0.3, 28.0.2, 28.0.3
System Images: android-25 | Google Play Intel x86 Atom, android-26 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-28 | Google Play Intel x86 Atom
IDEs:
Android Studio: 3.3 AI-182.5107.16.33.5199772
Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
react: 16.6.3 => 16.6.3
react-native: 0.58.6 => 0.58.6
Confirm, I have the same issue with nested horizontal scrolling. Please reopen, environment info added.
Have the same issue
Same issue here
+1 any fix regarding this?
Having the same issue. nestedScrollEnabled property works fine for vertical/vertical or vertical/horizontal (and vice versa) but seems to have no effect for nested horizontal scrollviews inside of another horizontal scrollview. However, i found some kind of workaround for this. This is a bit hacky and does not work perfectly, as you have to actually drag the inner view, but it works. You can capture the onTouchStart, onTouchEnd and onTouchCancel Events of the inner scrollview and set scrollEnabled on the outer scrollview to true or false correspondingly.
I'm experiencing the same issue. @smm76 yep, tried this hackish workaround too, but it doesn't feel 'fluid' enough.
Please reopen the issue.
@zhongwuzw , can you please re-open this issue or please tell any other collaborator to re-open it, since the @react-native-bot closed it.
For the brave hearts who fight with this issue, here's my workaround.
I have a horizontal <FlatList />
(parent) and a horizontal <ScrollView />
(child).
On my inner ScrollView
(child) I am disabling the <FlatList />
(parent) scroll onTouchStart
and I am enabling it back onScrollEndDrag
, similarly like @smm76 suggested. But additionally, I'm doing this throttle magic, which kind of solves all the little edge cases when the user doesn't immediately start dragging.
import throttle from 'lodash/throttle';
...
<ScrollView
horizontal={true}
scrollEventThrottle={16}
// ... bla bla
onTouchStart={() => {
if (Platform.OS === 'android') {
this.props.onTouchStartDisableScrollOnAndroid(); // disables parent scroll
// If the `onScrollEndDrag` event is not fired almost immediately
// after this one (and user doesn't start dragging)
// fire up `onTouchEndEnableScrollOnAndroid` and enable back
// the parent horizontal view scroll.
// This may happen when the user quickly taps on the component
// but doesn't start dragging.
this.throttledOnScrollEndDragOnAndroid = throttle(
this.props.onTouchEndEnableScrollOnAndroid, // enables parent scroll
300,
{
leading: false,
},
);
this.throttledOnScrollEndDragOnAndroid();
}
}}
onScrollEndDrag={() => {
if (Platform.OS === 'android') {
this.props.onTouchEndEnableScrollOnAndroid(); // enables parent scroll
if (this.throttledOnScrollEndDragOnAndroid) {
this.throttledOnScrollEndDragOnAndroid.cancel();
}
}
}}
>
/* content */
</ScrollView>
on all the scrollviews add prop nestedScrollEnabled, including the nested scrollview!
Same problem for me, with:
<FlatList horizontal nestedScrollEnabled={true}>
<ScrollView horizontal nestedScrollEnabled={true}>
</ScrollView>
</FlatList>
And when you try to scroll the child horizontally it scrolls the parent :(
Oh No. I'm facing this as well. Nested horizontal scrollviews doesn't work on Android. nestedScrollEnabled
has no effect in this case. Still happening on react-native 0.61.
I made this Snack with a reproduction: https://snack.expo.io/@brunolemos/nested-scrollview
@andreicoman11 @makovkastar @aamalric @astreet I checked the file blame and noticed you contributed a lot to the ReactHorizontalScrollView.java file. I was wondering (hoping) if you have any insight of what could be causing the issue above and what the fix could look like?
@brunolemos My contribution was just about preventing scrolling with D-Pad key events when scroll is disabled, nothing to do with nested scroll with touch events... Looking at the code I don't really see why it's not working, there's no difference between vertical and horizontal scroll managers code for Android, they both call:
ViewCompat.setNestedScrollingEnabled(view, value);
I used React Native Swiper for this purpose.(Nested Scrolling) EDIT: React Native Swiper used ViewPager before the latest release,now it is not working in the newer version,One thing i have seen is that viewpager is replaced by ScrollView now,Is the answer suggested by @brunolemos a good to go solution for now? On Tue 8 Oct, 2019, 12:15 Alexandre AMALRIC, notifications@github.com wrote:
@brunolemos https://github.com/brunolemos My contribution was just about preventing scrolling with D-Pad key events when scroll is disabled, nothing to do with nested scroll with touch events... Looking at the code I don't really see why it's not working, there's no difference between vertical and horizontal scroll managers code for Android, they both call:
ViewCompat.setNestedScrollingEnabled(view, value);
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/facebook/react-native/issues/21436?email_source=notifications&email_token=AGIXKMVCYDBVR5RNE5CRYFDQNQUBTA5CNFSM4FYGYUC2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEATA3HQ#issuecomment-539364766, or mute the thread https://github.com/notifications/unsubscribe-auth/AGIXKMXAMPFJ6IVEMKYFPVLQNQUBTANCNFSM4FYGYUCQ .
I found an easy workaround!
If we use the ScrollView
from react-native-gesture-handler
everything works as expected.
import { ScrollView } from 'react-native'
import { ScrollView as GestureHandlerScrollView } from 'react-native-gesture-handler'
<ScrollView horizontal>
<GestureHandlerScrollView horizontal />
</ScrollVIew>
You can have nested horizontal FlatList
s like this:
<FlatList {...props} renderScrollComponent={p => <GestureHandlerScrollView {...p} />} />
Updated the snack with this workaround: https://snack.expo.io/@brunolemos/nested-scrollview
Maybe someone can check what react-native-gesture-handle
is doing and bring the same workaround to the core of react-native
.
@brunolemos nice one! Just tried on a real device and it worked! Weird anyway, how does the gesture-handler implementation differ from native ScrollView? Is this down to touch recognition?
@brunolemos Thanks so much!
It's scrolling but now the nestedScrollEnabled prop not works.
Any idea?
@cklinx why do you still need this prop if it's already scrolling correctly? also confirm that you are using the latest version of both react-native
(0.61.2) and react-native-gesture-handler
(1.4.1).
@brunolemos the scroll is working but when the child's scrollview reach end the parent's scroll will not fire. You can see it in your expo example also!
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.
.
I have the same problem. If you find the solution, please share.
@ertandrn try to use ScrollView Component of react-native-gesture-handler
instead of the one from react-native
as suggested by @brunolemos . This seems to be the only non-hacky solution atm and works as expected
@smm76 i tried, but the problem persists.
@ertandrn could you provide some code or a demo then? To be sure, take a look at this expo snack: https://snack.expo.io/@brunolemos/nested-scrollview This works for me.
@smm76 i tried the same code on the link but it doesn't work. (https://snack.expo.io/@brunolemos/nested-scrollview)
same here
after some tests, I found that if you give both internal views(cards for ex.) and scrollview content style pixel based width, it will work but if you give % width it just won't scroll but renders without an issue.
@brunolemos your solution is working on snack but it is not working on emulator or real devices
Same here
I stumble in similar issue. iOS is fine but when test on Android, horizontal ScrollView
won't scroll. The horizontal ScrollView
that set overflow='hidden'
seem not working too.
My setup: horizontal ScrollView
is inside vertical ScrollView
, I have item list inside horizontal ScrollView
. After sometime I manage to fix it, so my code is like following:
<ScrollView style={{flex:1}}>
...
<ScrollView horizontal style={{width:W-40, overflow:'hidden', marginHorizontal:20}} >
...
</ScrollView>
...
</ScrollView>
Some to point out for horizontal ScrollView
:
was using flex:1
and on Android it will make the ScrollView
will have content/children width, making so that it can't be swiped and overflow:'hidden'
not working
with the use of horizontal margin, it can't use width:'100%'
too as in Android and iOS will adopt parent's width, and while the swipe is working, it make the overflow:'hidden'
seem not working
not using nestedScrollEnabled prop
My environment: "react": "16.9.0", "react-native": "0.61.5",
The workaround provided by @brunolemos works for me on Android . Does anyone know why the ScrollView from react-native-gesture-handler
works, and the core RN ScrollView does not?
I found an easy workaround!
If we use the
ScrollView
fromreact-native-gesture-handler
everything works as expected.import { ScrollView } from 'react-native' import { ScrollView as GestureHandlerScrollView } from 'react-native-gesture-handler' <ScrollView horizontal> <GestureHandlerScrollView horizontal /> </ScrollVIew>
You can have nested horizontal
FlatList
s like this:<FlatList {...props} renderScrollComponent={p => <GestureHandlerScrollView {...p} />} />
Updated the snack with this workaround: https://snack.expo.io/@brunolemos/nested-scrollview
Maybe someone can check what
react-native-gesture-handle
is doing and bring the same workaround to the core ofreact-native
.
Appreciate the solution! This issue is a bit dated, if anyone still has this issue and none of these solutions work, feel free to open a new issue.
I mean shouldn't this issue be fixed in react-native core? The solution can't be just use a ScrollView from a different library.
@scousino relooking at this 100% agree. Thanks for flagging. It should be fixed in core.
I have a similar problem, but my structure is like this:
`
` And the FlatList does not scroll. How can this problem be solved now?
Definitely I think this should be solved in the core
Need to fix nested horizontal scroll on Android in the core. ScrollView
from react-native-gesture-handler
works perfect!
For the ScrollViews to work as expected, nested or otherwise, you need to specify their boundaries. Boundaries are set in "style" property of the ScrollViews.
import { ScrollView } from 'react-native'
//
<ScrollView
style={{
width: "equal-to-or-less-than viewport width",
height: "equal-to-or-less-than viewport height"
}}
contentContainerStyle={{"..."}}
horizontal
>
<ScrollView
style={{
width: "lower-than Parent-ScrollView width",
height: "lower-than Parent-ScrollView height"
}}
contentContainerStyle={{"..."}}
>
</ScrollView>
</ScrollVIew>
NOTE: Always Set explicit boundaries(width/height) for Scrollview. So basically all sides of the border have to appear on the screen
pr https://github.com/facebook/react-native/pull/28138 would manually implement this feature, was closed in favour of pr https://github.com/facebook/react-native/pull/18299 which adds a prop for ViewCompat.setNestedScrollingEnabled
Enable or disable nested scrolling for this view.
If this property is set to true the view will be permitted to initiate nested scrolling operations with a compatible parent view in the current hierarchy. If this view does not implement nested scrolling this will have no effect. Disabling nested scrolling while a nested scroll is in progress has the effect of stopping the nested scroll.
By my experience writing pr https://github.com/facebook/react-native/pull/29025, the onTouchEvent
in the ReactScrollView
child does not include logic to handle nested scrolling
CLICK TO OPEN TESTS RESULTS
| **IOS** | **ANDROID** | |:-------------------------:|:-------------------------:| | | |
The current ReactScrollView onTouchEvent
only detects when user finger stops scrolling and then delegates to the parent view.
The solutions:
1 - Inherit this functionality from other classes (for ex. NestedScrollView)
2 - Enhacing the onTouchEvent
using a logic similar to my pr https://github.com/facebook/react-native/pull/29025 which adds possibility to scroll TextInput that are included in a ScrollView
The logic detects:
horizontal
or vertical
)CLICK TO OPEN TESTS RESULTS
| **HORIZONTAL** | **AFTER** | |:-------------------------:|:-------------------------:| | | |
I'll troubleshoot and try to prepare a PR.
I would like to ask @tuncaulubilge that wrote pr https://github.com/facebook/react-native/pull/18299 which adds a prop nestedScrollEnabled
if he could give me feedback before starting to work on this, as it is a big change, but seems essential to use the functionality included in his pr https://github.com/facebook/react-native/pull/18299 :pray:
Enable or disable nested scrolling for this view.
If this property is set to true the view will be permitted to initiate nested scrolling operations with a compatible parent view in the current hierarchy. If this view does not implement nested scrolling this will have no effect.
seems to me that the problem here is missing implementation of the NestedScroll
functionality in the ReactScrollView
This interface should be implemented by View subclasses that wish to support dispatching nested scrolling operations to a cooperating parent ViewGroup.
as my understanding when using <ScrollView nestedScrollEnabled />
the prop will create a final instance
of NestedScrollingChildHelper
public class ReactScrollView extends ScrollView implements NestedScrollingChild {
private NestedScrollingChildHelper helper = new NestedScrollingChildHelper(this);
}
Classes implementing this interface should create a final instance of a NestedScrollingChildHelper as a field and delegate any View methods to the NestedScrollingChildHelper methods of the same signature. For each View method that has a matching method signature in this class, delegate the operation to the helper instance in an overridden method implementation. This implements the standard framework policy for nested scrolling.
public class ReactScrollView extends ScrollView implements NestedScrollingChild {
private NestedScrollingChildHelper helper = new NestedScrollingChildHelper(this);
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// our implementations of onScrollChanged
super.onScrollChanged(l, t, oldl, oldt);
}
@Override
public boolean isNestedScrollingEnabled() {
return helper.isNestedScrollingEnabled();
}
@Override
public void setNestedScrollingEnabled(boolean enabled) {
helper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean startNestedScroll(int axes) {
return helper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
helper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return helper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
return helper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return helper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return helper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return helper.dispatchNestedPreFling(velocityX, velocityY);
}
}
Other Links:
https://stackoverflow.com/questions/35510250/how-to-properly-implement-nestedscrollingchild-on-a-webview https://stackoverflow.com/questions/29885067/how-to-implement-nestedscrolling-on-android https://stackoverflow.com/questions/30089084/android-issue-with-implementing-flings-in-nestedscrollview
Thanks a lot @isnotgood for pr https://github.com/facebook/react-native/pull/28138 which seems to implement this solution.
I did not study much the ReactNativeGestureHandler ScrollView horizontal
component https://github.com/facebook/react-native/issues/21436#issuecomment-539415308 which does not have this issue
I'm curious in the reason @isnotgood closed pr https://github.com/facebook/react-native/pull/28138, maybe performance limitation compared to ReactNativeGestureHandler?
the lookup code could be performance bottleneck in some extreme cases and I'm willing to optimize it further if it will be considered
Tomorrow I will give a further look in the ReactNativeGestureHandler implementation to see if I can understand and apply the same solution to HorizontalScrollView.java
I am also considering creating a pull request to add information about this bug in the ScrollView docs so that the solution is easier to find. Thanks
@fabriziobertoglio1987 there was no problem, I just closed it as there was no interest from maintainers 😄 Feel free to resurrect the PR on your own if you think it's worth the effort.
I re-opened the PR with the permission of @isnotgood
Environment
Binaries: npm: 5.6.0 - C:\Program Files\nodejs\npm.CMD IDEs: Android Studio: Version 3.1.0.0 AI-173.4907809 Package: "react": "16.5.0", "react-native": "0.57.1", Device Info: Android Version: 5.0.2 LRX22G
Description
I think nestedScrollEnabled prop for ScrollView only work in vertical. I don't know what's wrong in my code or something else. Just change little bit in height and width length and add/remove nestedScrollEnabled. Could anyone help me in this issue.
Reproducible Demo
VERTICAL
HORIZONTAL