Ответ 1
В своем panresponder для внутреннего, попробуйте установить это:
onPanResponderTerminationRequest: () => false
Я пытаюсь вставить ScrollViews в React Native; горизонтальный свиток с вложенными вертикальными свитками.
Вот пример:
var Test = React.createClass({
render: function() {
return (
<ScrollView
style={{width:320, height:568}}
horizontal={true}
pagingEnabled={true}>
{times(3, (i) => {
return (
<View style={{width:320, height:568}}>
<ScrollView>
{times(20, (j) => {
return (
<View style={{width:320, height:100, backgroundColor:randomColor()}}/>
);
})}
</ScrollView>
</View>
);
})}
</ScrollView>
);
},
});
AppRegistry.registerComponent('MyApp', () => Test);
Наружный скроллер работает безупречно, но внутренний палочка, когда вы касаетесь его во время движения. Я имею в виду: если вы прокрутите, поднимите свой палец и коснитесь его снова, пока он все еще движется с импульсом, он останавливается и не реагирует вообще, чтобы коснуться движений. Чтобы прокрутить больше, вам нужно снова поднять палец и снова коснуться.
Это настолько воспроизводимо, что это похоже на что-то вроде Жест-ответчика.
Кто-нибудь видел эту проблему?
Как бы я даже начал отлаживать это? Есть ли способ увидеть, что реагирует на касания, предоставление и освобождение, и когда?
Спасибо.
Обновление:
Похоже, что это система респондентов, помещая onResponderMove
прослушиватели на внутренний и внешний скроллеры:
<ScrollView
onResponderMove={()=>{console.log('outer responding');}}
...
<ScrollView
onResponderMove={()=>{console.log('inner responding');}}>
...
Ясно, что внешний ScrollView захватывает управление. Вопрос, я думаю, заключается в том, как остановить внешний скроллер от контроля при попытке прокрутки по вертикали? И почему это происходит только при попытке прокрутить уже движущийся внутренний ScrollView?
В своем panresponder для внутреннего, попробуйте установить это:
onPanResponderTerminationRequest: () => false
Изменить node_modules/react-native/Libraries/Components/ScrollResponder.js
: Строка 136 (См. ОБНОВЛЕНИЕ):
scrollResponderHandleScrollShouldSetResponder: function(): boolean {
return this.state.isTouching;
},
ОБНОВЛЕНИЕ: я считаю, что если прокрутка в настоящее время оживляет анимацию и хочет стать ответчиком, она отклонит ее. Строка 189 в ScrollResponder.js. Поэтому я изменяю Line 340, и он работает для меня:
scrollResponderIsAnimating: function(): boolean {
// var now = Date.now();
// var timeSinceLastMomentumScrollEnd = now - this.state.lastMomentumScrollEndTime;
// var isAnimating = timeSinceLastMomentumScrollEnd < IS_ANIMATING_TOUCH_START_THRESHOLD_MS ||
// this.state.lastMomentumScrollEndTime < this.state.lastMomentumScrollBeginTime;
// return isAnimating;
return false;
},
Вы можете посмотреть здесь: https://github.com/facebook/react-native/issues/41
Обтекание прокручиваемым содержимым вложенного ScrollView с исправлением этого для меня на Android:
<ScrollView>
...
<ScrollView horizontal>
<TouchableWithoutFeedback>
{ /* your scrollable content goes here */ }
</TouchableWithoutFeedback>
</ScrollView>
</ScrollView>
@IlyaDoroshin и @David Nathan ответ указали мне в правильном направлении, но мне пришлось обернуть каждый элемент в scrollview с сенсорным, а не с одним касанием для всего.
<ScrollView>
...
<ScrollView horizontal>
{items.map(item => (
<TouchableWithoutFeedback>
{ /* your scrollable content goes here */ }
</TouchableWithoutFeedback>
))}
</ScrollView>
</ScrollView>