React Native FlatList зі стовпцями, ширина останнього елемента


76

Я використовую FlatList, щоб показати список елементів у двох стовпцях

<FlatList style={{margin:5}}
  data={this.state.items}
  numColumns={2}
  keyExtractor={(item, index) => item.id }
  renderItem={(item) => <Card image={item.item.gallery_image_url} text={item.item.name}/> }
/>

Компонент картки - це лише вигляд із деякими стилями:

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130}} ></View>

Він працює нормально, але якщо кількість елементів непарна, останній рядок містить лише один елемент, і цей елемент розтягується на всю ширину екрана.

Як я можу встановити для елемента однакову ширину для інших?

введіть тут опис зображення

Відповіді:


35

Є кілька речей, які ви можете спробувати тут.

A) Встановлення заздалегідь визначеної ширини для картки (можливо, дорівнює висоті, яку ви встановили?). Тоді можна використовуватиalignItems для того, щоб карта була розташована посередині або ліворуч - Не впевнені, що ви хотіли тут.

Б) Якщо є парна кількість карток, ви можете додати порожній вигляд в кінці, щоб заповнити цей простір. Я вважаю цей метод досить незграбним, але корисним при спробі залишити простір для майбутніх елементів.

В) Просто використовуйте alignItems: 'space-between, я люблю використовувати це для центрування елементів, але вам доведеться визначити ширину або використовувати щось на зразокflex:0.5

Я пропоную більше дослідити flexbox, щоб допомогти вам у цьому, оскільки важко розказати контекст цієї ситуації. Я припускаю, що наведені вище методи допоможуть, але якщо ні, ось кілька посилань, на які ви можете ознайомитись -

Перше посилання

Друга ланка

Третя ланка Посилання порушено

Сподіваюся, це допомагає. Якщо вам потрібні додаткові роз’яснення - просто запитайте


1
B - це розумний хак. Варіант A зайвий, його можна просто встановити для вирівнювання, як ті, додавши flexWrap. Яка мета numColumns у такому випадку?
eden

Я неохоче йшов з B, але я це зробив, і хоча це хак, він чудово працює, і мені не потрібно вказувати ширину елементів (я хочу, щоб вони пристосовувались до доступної ширини)
Escobar5,

@Ryan: Я хочу, щоб перша клітинка була повністю розтягнута і з 3 колонками, що мені робити ??
Абхішек Тапліал

Варіант C: встановити Flex: 0,5 Працює для мене.
Аман Гоял

50

для вашого випадку використовуйте флекс: 1/2

отже: Ваш товар повинен мати гнучкість 1 / (кількість стовпців), якщо у Вас 3 стовпці, Ваш товар повинен мати гнучкість: 1/3


2
Не знаю, чому це не позначено як відповідь. Це найпростіше і правильне рішення!
tnort173

10
коли я даю flex: 1/2, ширина останнього елемента більша за попередні. Як ми можемо виправити цю будь-яку ідею, будь ласка
iOSDev

Geniussss !!! це спрацювало! найкращий обхідний шлях коли-небудь. Дякую, людино, ти заслуговуєш на правильну відповідь
msqar

Я спробував це, і, як сказав "iOSDev", окремий елемент у останньому рядку трохи ширший, ніж перший елемент попередніх рядків. Тому це рішення для мене не працює
se22as

@ tnort173, оскільки це не працює; останній предмет все ще більший за інші.
Абдул Садік Ялчин

18

Ви можете спробувати отримати поточну ширину пристрою за допомогою Dimensions, прорахувати кількість залежно від кількості стовпців, які ви хочете відтворити, мінус поля та встановити це як minWidth і maxWidth.

Наприклад:

const {height, width} = Dimensions.get('window');
const itemWidth = (width - 15) / 2;

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', minWidth: {this.itemWidth}, maxWidth: {this.itemWidth}, height: 130}} ></View>

Потрапив у таку ж ситуацію, і я, безумовно, віддаю перевагу цьому рішенню. Мало того, що це простіше, але це має більше сенсу, оскільки в кінцевому рахунку ми хочемо обмежити flex:1у випадку з непарною колонкою
Арно Морет

Дуже мило. Дякую!
Марк

Помилка отримання: типи властивостей 'style' несумісні
Ghost

@Ghost ти використовуєш Typescript? Якщо так, ця помилка може бути пов’язана із
Typescript

9

Це найчистіший спосіб стилізувати a FlatListзі стовпцями з рівним інтервалом:

    <FlatList style={{margin:5}}
        numColumns={2}                  // set number of columns 
        columnWrapperStyle={style.row}  // space them out evenly
        
        data={this.state.items}
        keyExtractor={(item, index) => item.id }
        renderItem={(item) => <Card image={item.item.gallery_image_url} text={item.item.name}/> }
    />       

    const style = StyleSheet.create({
        row: {
            flex: 1,
            justifyContent: "space-around"
        }
    });

6

Причиною цього є те, що ваша картка має стиль flex: 1, тому вона намагатиметься розширити весь простір, що залишився. Ви можете це виправити, додавши maxWidth: '50%'у свій стиль картки

<View style={{ flex: 1, margin: 5, backgroundColor: '#ddd', height: 130, maxWidth: '50%'}} ></View>

найпростіше рішення
Мухаммад Ашфак

1

Пропозиція @Emilius Mfuruki хороша, але якщо у вас є текст із різною довжиною, він не працює ідеально. Потім використовуйте цю ширину всередині перегляду елемента:

const {height, width} = Dimensions.get('window');
const itemWidth = (width - (MarginFromTheSide * 2 + MarginInBetween * (n-1))) / n;

У використанні FlatList:

columnWrapperStyle={{
            flex: 1,
            justifyContent: 'space-evenly',
          }}

Працює ідеально.


Я зробив щось подібне. Тільки для уточнення, MarginFromTheSideце горизонтальне поле екрана, а MarginInBetweenполе між кожним стовпцем. Отже, ви отримуєте доступну ширину для FlatList, видаляєте поле і ділите його на кількість стовпців, таким чином у вас є ширина кожного елемента :)
Рафаель Таварес


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.