これは、私が達成したいことについて(品質が低下した)GIFです。
画面の半分に配置されているscrollview
があります。
そのscrollview
を上にドラッグし、特定の位置に到達したら、drag touch event
をscrollview
自体に送信して、スクロールを続行できるようにします。
contentContainerStyle
に半画面のパディングトップを追加します。うまくいきましたが、背後のビューをクリックできませんでした。スクロールビューの空の領域をクリックする方法はありますか?それに応じてビューを上に移動するために、スクロール位置も検出しようとしました
<ScrollView onScroll={event => moveScrollViewUpIfNeeded(event)}>
...
</ScrollView>
iOSシミュレーターでテストしたところ機能しませんでした。イベントは発生しません。 React Native Docs は、onScroll
が機能するためにscrollEventThrottle
が必要であることを示しています。ただし、scrollEventThrottle
は iOSで利用可能 のみです。そして私の場合、私はAndroidでもそれを望んでいます。
これが正常に達成された場合、別のUI問題に直面するはずです。ScrollViewを上にドラッグすると、ビューがまだ希望の位置にないときにスクロールできないようにするにはどうすればよいですか?
それで、これを達成するためのヒントを教えてください:)?
ありがとうございました、
私はいくつかのオプションを試しました。これは、パフォーマンス面で最適に機能する私のソリューションです。もちろん、これは実際の例にすぎません。ニーズに完全に一致させるには、さらに最適化する必要がある場合があります。
基本的な考え方は、オーバーレイの背景に常にマップを保持することです。オーバーレイは絶対的に配置され、2つのビューを含みます。 1つのビューは透明で、マップを表示および制御できます。もう1つのビューには実際のScrollViewが含まれています。トリックは、親オーバーレイのpointerEvents="box-none"
を設定し、マップと対話するビューのpointerEvents="none"
でpointerEventsを無効にすることです。
基本的なレンダリング方法:
<SafeAreaView style={{flex: 1}}>
<MapView
initialRegion={region}
style={{height: HEIGHT, width: WIDTH}}
/>
<View pointerEvents="box-none"style={{height: HEIGHT, width: WIDTH, position: 'absolute'}}>
<View pointerEvents="none" style={{height: this.state.height, backgroundColor: 'transparent'}} />
<View style={{ height: HEIGHT-this.state.height, backgroundColor: 'white'}}>
<ScrollView onScroll={(e) => this._onScroll(e)} scrollEventThrottle={10} >
-- content of scrollview goes here ---
</ScrollView>
</View>
</View>
</SafeAreaView>
スクロール機能:
ScrollViewを下にスクロールする場合、空のビューを縮小して、ScrollViewがフルスクリーンになるようにします。したがって、ScrollViewのonScroll
メソッドをリッスンします。以下のコードとコメントを参照してください。
_onScroll(e){
// from the nativeEvent we can get the contentOffsett
var offset_y = e.nativeEvent.contentOffset.y;
if (offset_y > 0 ) {
if (this.state.height>=0){
// we are scrolling down the list, decrease height of the empty view
this.setState({height: this.state.height-offset_y});
}
}
if (offset_y <0){
if (this.state.height <= this.state.mapHeight){
// we are scrolling up the list, increase size of empty view/map view
this.setState({height: this.state.height-offset_y});
}
}
}
ScrollViewのscrollEventThrottle
プロパティを使用すると、_onScroll
メソッドを呼び出す頻度を制御できます。 (ここではおそらく微調整が必要です)
これを達成するには、react-native-reanimated-bottom-sheetを使用します。 https://github.com/osdnk/react-native-reanimated-bottom-sheet
MapViewとBottomViewの両方を1つのScrollView
に配置することをお勧めします。
それは自然なスクロール動作を保存し、下にスクロールする際の白い縞や上にスクロールする際にトップビューが消えるといった副作用を防ぎます。ここでの主な問題は、MapView
を「フリーズ」させる方法です。
スクロールイベントに対して相対的にMapView
コンテナー内のAnimated
を変換することによって視差効果を使用するのは良いことです。 アニメーション化されたライブラリアニメーション化可能なコンポーネント はそのような問題の良い解決策になると思います:
_ scroll = new Animated.Value(0)
render() {
return <Animated.ScrollView ...
onScroll={Animated.event([{nativeEvent: {contentOffset: {y: this.scroll}}}], {useNativeDriver: true})}>
<Animated.View
style={
{ ...transform:
[{translateY: Animated.multiply(this.scroll, 0.8)}]}}>
<MapView />
</Animated.View>
<BottomView />
</Animated.ScrollView>
}
_
実際に視差効果が必要ない場合は、Animated.multiply(this.scroll, 0.8)
を単に_this.scroll
_に置き換えることができます
ここで完全な例を見ることができます: コード例