ScrollView snapToInterval и snapToAlignment не работают для списка текстовых элементов

Я пытаюсь воссоздать вид с горизонтальной прокруткой, похожий на нижнюю часть камеры Instagram. Это горизонтальный список текстовых элементов, каждый из которых привязывается к центру при прокрутке мимо него. Это позволяет вам выбирать различные настройки камеры. Вот скриншот:

ScrollView snapToInterval и snapToAlignment не работают для списка текстовых элементов

Однако я не могу заставить работать snapToInterval или snapToAlignment. Вместо этого scrollView выравнивается по гибкому началу и не имеет анимации привязки. Вот гифка (надо еще доработать):

ScrollView snapToInterval и snapToAlignment не работают для списка текстовых элементов

Вот полный компонент:

'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;

Что я делаю неправильно? Любая помощь приветствуется.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
3 091
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В конечном итоге я решил это с помощью сторонней библиотеки реагировать-родной-оснастки-карусель. Я хотел избежать этого, но не видел другого выхода. На момент написания библиотека выглядела хорошо используемой и поддерживаемой, а документация отличная.

Вот как выглядит окончательный код:

'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>

Другие вопросы по теме