Я пытаюсь воссоздать вид с горизонтальной прокруткой, похожий на нижнюю часть камеры Instagram. Это горизонтальный список текстовых элементов, каждый из которых привязывается к центру при прокрутке мимо него. Это позволяет вам выбирать различные настройки камеры. Вот скриншот:
Однако я не могу заставить работать snapToInterval или snapToAlignment. Вместо этого scrollView выравнивается по гибкому началу и не имеет анимации привязки. Вот гифка (надо еще доработать):
Вот полный компонент:
'use strict';
import React from 'react';
import { View, Text, ScrollView } from 'react-native';
const CameraSlider = () => (
<View style = {styles.sliderViewStyle}>
<ScrollView
horizontal
snapToInterval = {100}
snapToAlignment = "center"
decelerationRate = "fast"
>
<Text style = {styles.textContentStyle}>PHOTO</Text>
<Text style = {styles.textContentStyle}>VIDEO</Text>
</ScrollView>
</View>
);
const styles = {
textContentStyle: {
color: 'white',
width: 100,
fontSize: 16
},
sliderViewStyle: {
height: 40
}
};
export default CameraSlider;
Что я делаю неправильно? Любая помощь приветствуется.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В конечном итоге я решил это с помощью сторонней библиотеки реагировать-родной-оснастки-карусель. Я хотел избежать этого, но не видел другого выхода. На момент написания библиотека выглядела хорошо используемой и поддерживаемой, а документация отличная.
Вот как выглядит окончательный код:
'use strict';
import React from 'react';
import { View, Text, Dimensions } from 'react-native';
import Carousel from 'react-native-snap-carousel';
const SCREEN_WIDTH = Dimensions.get('screen').width;
const MediaTypeSlider = props => {
const renderItem = ({ item }) => (
<Text style = {styles.textContentStyle}>{item.toUpperCase()}</Text>
);
return (
<View style = {styles.sliderViewStyle}>
<Carousel
data = {props.mediaTypes}
renderItem = {renderItem}
sliderWidth = {SCREEN_WIDTH}
itemWidth = {80}
itemHeight = {50}
sliderHeight = {50}
onSnapToItem = {props.toggleMediaType}
/>
</View>
);
};
const styles = {
textContentStyle: {
color: 'white',
width: 80,
fontSize: 17,
textAlign: 'center',
fontWeight: '500'
},
sliderViewStyle: {
height: 50,
alignItems: 'center'
}
};
export default MediaTypeSlider;
Вот оно в действии:
потому что прокрутка касалась края содержимого слева, и вы больше не могли прокручивать влево. Есть несколько способов обойти это. Один из них: настройка contentInset для левого и правого. Другой способ, который я использовал раньше: вам нужно выполнить некоторые вычисления в соответствии с вашими потребностями и просто сделать так, чтобы у самого левого «View» было поле слева, которое позволяет прокручивать сам текст по центру, поскольку слева все еще есть контент. То же самое относится и к самому правому «обзору».
Вот пример моего кода:
<ScrollView
ref = {(scrollView) => { this.scrollView = scrollView; }}
style = {styles.container}
horizontal
decelerationRate = {0}
snapToInterval = {80}
pagingEnabled = {Platform.OS === 'android'}
snapToAlignment = "center"
overScrollMode = "never"
scroll
contentInset = {{
top: 0,
left: 0,
bottom: 0,
right: 0,
}}
>
<View style = {[styles.view, { backgroundColor: 'red', marginLeft: 160, paddingLeft: 60 }]} />
<View style = {styles.view} />
<View style = {[styles.view, { backgroundColor: 'red' }]} />
<View style = {styles.view} />
<View style = {[styles.view, { backgroundColor: 'red' }]} />
<View style = {[styles.view, { marginRight: 160, paddingRight: 60 }]} />
</ScrollView>
и вот стиль, который я использовал для этого примера:
const styles = StyleSheet.create({
container: {},
view: {
marginTop: 100,
backgroundColor: 'blue',
width: 40,
marginLeft: 40,
height: 20,
borderRadius: 10,
// paddingHorizontal : 30
},
});
<View style = {[styles.view, { backgroundColor: 'red' }]} />
<View style = {styles.view} />
<View style = {[styles.view, { backgroundColor: 'red' }]} />
<View style = {[styles.view, { marginRight: 160, paddingRight: 60 }]} />
</ScrollView>