React Native FlatList - проблема с видимостью последнего элемента

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

 renderProducts() {
        if (this.props.loading === true) {
            return (
                <View style={Styles.spinnerStyle}>
                    <ActivityIndicator size='large' />
                </View>
            );
        }

        return (
                <FlatList
                    data={this.props.myProducts}
                    keyExtractor={(item) => item.id}
                    renderItem={({ item }) => (
                        <Card 
                            title={item.title} 
                            image={{ 
                                uri: item.image !== null ? item.image.src :'../resImage.jpg' 
                            }}
                        >
                            <Text style={{ marginBottom: 10 }}>
                                {item.body_html}
                            </Text>
                            <Button
                                icon={{ name: 'code' }}
                                backgroundColor='#03A9F4'
                                fontFamily='Lato'
                                buttonStyle={{ borderRadius: 0, marginLeft: 0, marginRight: 0, marginBottom: 0 }}
                                title='VIEW NOW' 
                            />
                      </Card>
                      )}
                />
        );
    }
    
    render() {
        return (
            <View>
                <View style={Styles.viewStyle}>
                    <Text style    {Styles.textStyle}>ProductsList</Text>
                </View>
                    { 
                        this.renderProducts() 
                    }
            </View>
        );
    }

person Muhammad Talha    schedule 13.09.2017    source источник
comment
... как вы видите На самом деле мы не можем, потому что вы не разместили код.   -  person bennygenel    schedule 13.09.2017
comment
посмотрите сейчас.   -  person Muhammad Talha    schedule 13.09.2017
comment
попробуйте добавить отступ в нижнюю часть FlatList Component. <FlatList style={{ paddingBottom: 20 }} ... />   -  person bennygenel    schedule 13.09.2017
comment
Эй, это единственное решение проблемы. Добавление marginBottom у меня тоже работает, но это похоже на взлом, не так ли?   -  person Anirudh    schedule 21.10.2017
comment
Спасибо. Это решило мою проблему :)   -  person Khalid Rahman    schedule 16.04.2018


Ответы (13)


Установите нижний отступ для контейнера содержимого <FlatList>:

<FlatList
    contentContainerStyle={{ paddingBottom: 20 }}
/>
person krish    schedule 26.07.2018
comment
Большой. Работал у меня. - person Aman Deep; 26.11.2019
comment
Зачем нам делать этот хак? - person SmallChess; 17.09.2020
comment
Работал у меня. Спасибо - person ABHIRAMAREDDY REDDY; 09.12.2020
comment
это сработало для меня, paddingBottom мне пришлось установить его как 350 (методом проб и ошибок) (размер элемента моего плоского списка выше). Но как найти необходимое заполнение? - person Raghu Vallikkat; 12.04.2021
comment
Это не работает, если высота содержимого изменяется динамически. Чтобы сделать все элементы FlatLIst видимыми, убедитесь, что родительский View должен иметь фиксированную высоту или ширину в зависимости от направления FlatList. - person Neeraj Sewani; 22.06.2021
comment
Ты мой новый бог - person Thomas Hagström; 02.07.2021

Добавьте {flex: 1} к тегу View, содержащему компонент Flatlist.

В моем случае,

const App = () => {
  return (
    <Provider store={createStore(reducers)}>
    <View style={{ flex: 1 }}>
      <Header headerText={'My App'} />
      <ScreenTabs /> // this is my content with FlatList 
    </View>
    </Provider>
  );
};

export default App;
person Ashish    schedule 26.12.2017
comment
Когда я это сделаю, мой список больше не будет виден. - person Christian; 28.03.2018
comment
Если ваш список не отображается, возможно, родительский View is not flex: 1, вам нужно найти, какой родительский вид не расширяется. - person Andrei Calazans; 04.04.2019
comment
<FlatList style={{flex: 1}} также работал у меня без родителей <View/>. Однако пришлось добавить {flex: 1} в основной вид контейнера. - person Muhammad Qasim; 03.09.2020

@Christian (я не могу комментировать, потому что моя репутация слишком низкая), вы не можете увидеть свой список с помощью flex: 1, потому что flex: 1 расширит компонент до родительского. Если у родителя нет flex: 1, он не будет растягиваться до родителя или экрана. Однако имейте в виду, что flex: 1 с SafeAreaView приведет к отображению нижней безопасной области. Это будет плохо выглядеть, если ваш SafeAreaView backgroundColor отличается от цвета фона вашего списка.

Моим старым обходным решением было добавить элемент в нижнюю часть массива элементов, но я все еще изучаю, как прокрутить мимо / под нижним полем безопасной области с помощью FlatList (именно так я нашел этот пост для начала).

Обновление: с помощью ListFooterComponent вы можете создать даже простой белый «нижний колонтитул» с высотой и / или полем.

Например (на вашем месте я бы не копировал и вставлял это напрямую ... несомненно, есть лучший способ обнаружить iPhone без рамки, особенно в 2019 году, когда у нас их больше одного)

ListFooterComponent={<View style={{ height: 0, marginBottom: 90 }}></View>}

Вот как я бы это сделал, используя пока высоту iPhoneX. Но это не гарантия будущего, поскольку условное условие нужно будет обновлять каждый раз, когда выходит новый iPhone без лицевых панелей:

ListFooterComponent={<View style={{ height: 0, marginBottom: noBezels ? 90 : 0 }}></View>}

Или у вас всегда может быть какой-то интервал внизу, например, загружаемый gif, сообщение ... что угодно.

ОБНОВЛЕНИЕ

Я узнал о response-native-device-info, у которого есть метод hasNotch (). Я считаю, что это полезно для стилизации iPhone без лицевых панелей, объединив hasNotch () с Platform.OS === 'ios'

ОБНОВЛЕНИЕ (снова) *

Я знаю, что это не по теме, но ...

В response-navigation есть SafeAreaView с возможностью не отображать эту нижнюю область.

import { SafeAreaView } from 'react-navigation';
<SafeAreaView forceInset={{ bottom: 'never' }} />
person jsonp    schedule 05.05.2018
comment
Привет, @jsonp, к сожалению, я не увидел твоего ответа, но решил, как и ты. Я хотел поблагодарить вас немного с опозданием за ваши усилия, даже когда я не смог вовремя прочитать ваше сообщение. Тогда спасибо! (также проголосовали за) - person Christian; 13.06.2018
comment
Использовал это, и это сработало, я безрезультатно пытался добавить представление с заданной высотой под компонентом плоского списка. Это устранило мою проблему с тем, что последний элемент списка частично перекрывался моей нижней навигацией. - person IronWorkshop; 09.01.2020
comment
jsonp К настоящему времени у вас достаточно представителей для комментариев. Но позвольте мне упомянуть, что даже если вы процитируете правило, которое вы нарушаете, оно все равно применимо к вам. Так что, если это не может быть случайно замечено как полезный ответ на сам вопрос, его необходимо удалить. Пожалуйста, перефразируйте это в ответ, основанный на, но заметно расширяющий ответ, который прокомментировал Chritian (или именно так я понимаю, что здесь произошло). Если вы не можете этого сделать и по-прежнему считаете, что это должен быть комментарий, превратите его в комментарий. (Я бы не стал. Вы знаете. Так что - попробуйте! :-) - person Yunnosch; 13.03.2020

Просто оберните его в представление с помощью flex: 1

<ParentView style={{flex:1}
    <View style={{flex:1}}>
    // Your flatlist
    <View>
</ParentView>

Также обратите внимание, что каждый родительский элемент этого «View», в который заключен Flatlist, также должен быть View с Flex 1. В противном случае ваш плоский список не будет виден.

person Amit    schedule 04.03.2020
comment
Также обратите внимание, что каждый родительский элемент этого View, в который заключен Flatlist, также должен быть View с Flex, равным 1. В противном случае ваш плоский список не будет виден. .... очень полезный комментарий! Спасибо. - person Shailesh Appukuttan; 17.05.2020

использовать contentContainerStyle свойства FlatList

<FlatList contentContainerStyle={{ paddingBottom: 20}} />
person S.Mahdi    schedule 18.08.2019

Вы можете попробовать это решение

Для Vertical FlatList:

<FlatList
 ListFooterComponent={<View />}
 ListFooterComponentStyle={{height:200}}
/>

Для Horizontal FlatList:

<FlatList
  contentContainerStyle={{paddingRight:40}}
/>
person jamal    schedule 09.07.2020

Для проблем с IOS вы можете применить некоторые специфические для IOS реквизиты:

<FlatList
  // ...
  contentInset={{top: 0, bottom: 20, left: 0, right: 0}}
  contentInsetAdjustmentBehavior="automatic"
  // ...  
/>

Решение с contentContainerStyle заполнением не казалось лучшим в целом для решения проблем IOS в безопасной области в моем случае.

person Florin Dobre    schedule 03.07.2019
comment
Мой плоский список был в модальном окне с фиксированной высотой. в моем случае это работает лучше, чем любое другое решение. - person Amit Bravo; 17.03.2020

Используйте свойство contentContainerStyle в плоском списке <FlatList contentContainerStyle={{paddingBottom: 10}} />

person Ichoku Chinonso    schedule 30.06.2020

Я видел ту же проблему в нашем гибридном приложении Android + iOS React Native. Мы встраиваем компонент FlatList в наши собственные пользовательские интерфейсы внутри фрагмента в Android, и нам не удалось выполнить прокрутку до последнего элемента в списке, хотя индикатор прокрутки показывал, что прокручивать нужно больше, ScrollView просто не прокручивается дальше. Я безуспешно пробовал все комбинации использования упаковки <View style={{flex:1}}> для обертывания FlatList, а также использования contentContainerStyle={{flexGrow:1}} в FlatList. В поисках подсказки выяснилось, что FlatList нуждается в абсолютной, предопределенной высоте на Android, чтобы можно было прокручивать вниз - он отлично работает на iOS, но на Android использование match_parent не сработает. Поскольку нам необходимо поддерживать все типы устройств, включая телефоны и планшеты, невозможно было заранее определить абсолютную высоту.

Чтобы исправить это, я создал собственный подкласс FrameLayout для размещения фрагмента ReactRootView, который переопределяет onLayout() для игнорирования измерений дочернего представления, заставляя представления иметь точные размеры FrameLayout, примерно как в Kotlin:

class StretchFrameLayout @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        for (child in children){
            if (child.visibility == View.GONE) continue
            child.updateLayoutParams {
                this.width = measuredWidth
                this.height = measuredHeight
            }
            if (needsRelayout){
                handler.postDelayed({child.requestLayout()},1)
            }
        }
        super.onLayout(changed, left, top, right, bottom)
    }
}
person Dhiraj Gupta    schedule 08.07.2020

Это сработало для меня.

<View style={{flex: 1}}>
    <FlatList
      style={{flex: 1}}
      data={data}
      renderItem={({item}) => (
        <ListItem item={item} onPress={() => handlePress(item)} />
      )}
    />
  </View>
person Suleiman AbdulMajeed    schedule 10.11.2020

Очень хорошо работает для меня

<FlatList
  data={data}
  contentContainerStyle={{ paddingBottom: 30 }}
  style={{height: '95%'}}
  renderItem={({ item, index }) => (
    <ListItem item={item} onPress={() => handlePress(item, index)} />
  )}
/>
person Pedro Ivo    schedule 26.03.2021

Это очень хорошо работает в моем случае:

  <FlatList
    data={todos}
    contentContainerStyle={{ height: '100%' }}
    renderItem={({ item }) => <Todos items={item} pressed={pressed} />}
  />
person abdul basit    schedule 13.04.2021

Я решил, что это contentInset={{ bottom: data.length * itemStyle.height, }} с itemStyle.height, когда 50 работает нормально.

person Esteban    schedule 11.05.2021