TL; DR; При отсутствии contentContainerStyle в ScrollView его содержимое может быть немного обрезано.

Прежде чем начать изучать (и одновременно работать) с React Native, я был довольно озадачен его системой стилей. В глубине души большинство из нас, вероятно, все еще им является. Есть несколько очень мощных библиотек, которые предоставляют вам красивые и готовые к использованию компоненты (например, React Native Paper - очень мощная библиотека, которая предоставляет вам компоненты, совместимые с Material Design), но в этой статье я хочу чтобы поговорить о разработке пользовательского компонента карты и предостережения, которое появляется при использовании ваших карт в ScrollView.

Стилизация содержимого ScrollView

В недавнем проекте, над которым я работал, мы немного пытались понять, почему тени на наших карточках не отображались должным образом во всем приложении. Потребовалось некоторое чтение и отладка, пока я не обнаружил эту волшебную опору ScrollView: contentContainerStyle.

Как упоминается в его официальной документации об этой опоре:

Эти стили будут применены к контейнеру содержимого представления прокрутки, который охватывает все дочерние представления.

Вот как это будет выглядеть:

<ScrollView contentContainerStyle={styles.scrollContainer}>{items}</ScrollView>

Ваш scrollContainer стиль будет выглядеть так:

scrollContainer: {
    paddingHorizontal: 2,
    paddingVertical: 2,
}

Попробуйте использовать ScrollContainer без передачи стиля содержимого. Может сработать, но поверьте мне, что если у вас есть предметы, которые отбрасывают тени, они не будут выглядеть так круто. В нашем случае общий вид приложения казался незавершенным, неуклюжим и на самом деле не хвастался отличным UX, внешним видом и ощущениями, которые были предоставлены нам нашим дизайнером. Мы были потрясены, увидев, насколько разные простые тени могут изменить.

Что насчет содержимого ScrollView?

Рад, что ты спросил! Я также хочу поделиться с вами некоторым кодом, который может пропустить посещение этого генератора теней (который я полностью рекомендую; он помогает вам с проблемой написания правильных и последовательных теней как на Android, так и на iOS).

cardContainer: {
    shadowColor: colors.SHADOW_COLOR,
    shadowOpacity: 0.5, 
    shadowRadius: 5.0,
    elevation: 3,    
    flex: 1, 
    alignItems: 'center',
    horizontalPadding: 8,
    verticalPadding: 8,
    borderRadius: 10,
}

Небольшое примечание: значения заполнения жестко запрограммированы для примера. Пожалуйста, не записывайте значения жестко в реальных проектах. Вместо этого извлеките их в файл показателей.

Сам компонент карты можно легко написать с нуля.

export interface CustomCardProps extends ViewStyle {
    children?: ReactNode;
    style?: ViewStyle;
}
const Card = (props: CustomCardProps) => {
    const { children, style, ...rest } = props;
    return (
        <View style={[styles.cardContainer, style]} {...rest}>
            {children}
        </View>);
};
export default Card;

Это самый простой скелет, который можно было бы иметь для пользовательского компонента карты. Вы начнете добавлять к нему больше. Может быть, обернуть View в TouchableOpacity и предоставить onPress опору. Мир твой.

Спасибо, что прочитали статью! Надеюсь, я кое-кого сэкономил.

Есть ли у вас какие-нибудь интересные советы и приемы пользовательского интерфейса, на изучение которых у вас ушло больше времени, чем вам хотелось бы?