スクロールの挙動総合見直し

This commit is contained in:
harukin-expo-dev-env
2025-08-26 17:39:55 +00:00
parent 7e0749a2f2
commit c25050f344

View File

@@ -5,6 +5,7 @@ import Animated, {
useAnimatedStyle,
useSharedValue,
runOnJS,
useAnimatedScrollHandler,
} from "react-native-reanimated";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
@@ -34,7 +35,6 @@ export const ExGridView: FC<{
const savedWidthX = useSharedValue(width);
const [scrollEnabled, setScrollEnabled] = useState(true);
const scrollRef = useRef<Animated.ScrollView>(null);
const [contentScrollPos, setContentScrollPos] = useState(0);
// ScrollViewの有効/無効を切り替える関数
const toggleScrollEnabled = useCallback((enabled: boolean) => {
@@ -71,6 +71,16 @@ export const ExGridView: FC<{
const animatedStyle = useAnimatedStyle(() => ({
width: widthX.value,
}));
// 時ヘッダーを横にスクロールしたときの処理
const scrollX = useSharedValue(0);
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
scrollX.value = event.contentOffset.x;
},
});
const stickyTextStyle = useAnimatedStyle(() => ({
transform: [{ translateX: scrollX.value }],
}));
return (
<GestureDetector gesture={composed}>
<Animated.ScrollView
@@ -78,12 +88,16 @@ export const ExGridView: FC<{
nestedScrollEnabled
pinchGestureEnabled={false}
scrollEnabled={scrollEnabled}
onScroll={(d) => {
setContentScrollPos(d.nativeEvent.contentOffset.x);
}}
onContentSizeChange={(d) => {
if (d < contentScrollPos) {
scrollRef.current?.scrollToEnd();
onScroll={scrollHandler}
onContentSizeChange={(contentWidth) => {
// 現在のスクロール位置を取得
const currentScrollX = scrollX.value;
const containerWidth = width - 50;
// コンテンツが画面からはみ出している場合のみ右端にスクロール
if (currentScrollX + containerWidth > contentWidth) {
const newScrollX = Math.max(0, contentWidth - containerWidth);
scrollRef.current?.scrollTo({ x: newScrollX, animated: true });
}
}}
ref={scrollRef}
@@ -128,7 +142,7 @@ export const ExGridView: FC<{
borderColor: "#ccc",
flexWrap: "nowrap",
fontSize: 12,
width: 50
width: 50,
}}
>
()
@@ -155,8 +169,19 @@ export const ExGridView: FC<{
}}
key={hour}
>
<Text style={{ fontSize: 15, zIndex: 1, backgroundColor: 'white', marginLeft: contentScrollPos }}>{hour}</Text>
<Animated.Text
style={[
{
fontSize: 15,
zIndex: 1,
backgroundColor: "white",
marginLeft: 0,
},
stickyTextStyle,
]}
>
{hour}
</Animated.Text>
</View>,
<View style={{ flexDirection: "row", position: "relative" }}>
{groupedData[hour].map((d, i) => (