React Native FlatList 最后一项可见性问题

Posted

技术标签:

【中文标题】React Native FlatList 最后一项可见性问题【英文标题】:React Native FlatList last item visibility issue 【发布时间】:2018-02-22 02:07:22 【问题描述】:

我正在获取产品列表,然后使用 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>
        );
    

【问题讨论】:

"...如你所见"实际上我们不能,因为你没有发布任何代码。 现在看看。 尝试在FlatList 组件的底部添加填充。 &lt;FlatList style= paddingBottom: 20 ... /&gt; 嘿,这是解决问题的唯一方法吗?添加一个 marginBottom 也对我有用,但这似乎有点 hack,不是吗? 谢谢。它解决了我的问题:) 【参考方案1】:

@krish 解决方案非常适合固定大小的列表项,但是作为 @Neeraj Sewani 说,它可能不适合动态尺寸列表项。

所以你可以像这样解决问题 - 如果方向是列 -:

<View  style=height: '90%'> 
<FlatList/> 
</View>

否则,-如果方向是行-:

<View  style=height: '90%', width:'90%'> 
<FlatList/> 
</View>

【讨论】:

【参考方案2】:

最新更新:

react-navigation 有一个 SafeAreaView,可以选择不显示底部区域。

import  SafeAreaView  from 'react-navigation';
<SafeAreaView forceInset= bottom: 'never'  />

以下旧回复:

您无法使用 flex: 1 看到您的列表,因为 flex: 1 会将组件增长到父组件。如果父级没有 flex: 1,它将不会拉伸到其父级或屏幕。但是请记住,带有 SafeAreaView 的 flex: 1 将导致显示底部安全区域。如果您的 SafeAreaView 背景颜色与列表背景的颜色不同,这看起来会很糟糕。

我以前的解决方法是在项目数组的底部添加一个项目,但我仍在探索如何使用 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、一条消息……随便什么。

更新 2:

我发现 react-native-device-info 有一个 hasNotch() 方法。通过将 hasNotch() 与 Platform.OS === 'ios' 结合使用,我发现这对于没有边框的 iPhone 的样式很有用 === 'ios'

【讨论】:

嗨@jsonp 不幸的是我没有看到你的回复,但我基本上像你一样解决了它。即使我无法及时阅读您的信息,我也想感谢您的努力,有点晚了。那谢谢啦! (也赞成) 使用了这个并且效果很好,我试图在平面列表组件下添加一个设置高度的视图无济于事。这解决了我的最后一个列表项被底部导航部分覆盖的问题。 @Yunnosch 很抱歉回复晚了。我不确定你所说的违反规则等是什么意思。如果你看到这个,你能解释一下吗? @Yunnosch Gotcha。我会牢记这一点,继续前进。谢谢。【参考方案3】:

我已经解决了 contentInset= bottom: data.length * itemStyle.height, itemStyle.height 为 50 的问题。

【讨论】:

【参考方案4】:

这对我来说效果很好:

  <FlatList
    data=todos
    contentContainerStyle= height: '100%' 
    renderItem=( item ) => <Todos items=item pressed=pressed />
  />

【讨论】:

【参考方案5】:

对我来说工作得很好

<FlatList
  data=data
  contentContainerStyle= paddingBottom: 30 
  style=height: '95%'
  renderItem=( item, index ) => (
    <ListItem item=item onPress=() => handlePress(item, index) />
  )
/>

【讨论】:

【参考方案6】:

&lt;FlatList&gt; 内容容器设置底部填充:

<FlatList
    contentContainerStyle= paddingBottom: 20 
/>

【讨论】:

我们为什么要这么做? 为我工作。谢谢 它对我有用,我必须将 paddingBottom 设置为 350(通过反复试验)(我的平面列表项大小更高)。但是我们如何找到所需的实际填充 如果内容的高度动态变化,这将不起作用。要使 FlatLIst 的所有项目可见,请确保 父项 View 应具有固定高度或宽度,具体取决于 FlatList 方向。 为我工作。谢谢!【参考方案7】:

这对我有用。

<View style=flex: 1>
    <FlatList
      style=flex: 1
      data=data
      renderItem=(item) => (
        <ListItem item=item onPress=() => handlePress(item) />
      )
    />
  </View>

【讨论】:

【参考方案8】:

你可以试试这个解决方案

对于VerticalFlatList

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

对于HorizontalFlatList

<FlatList
  contentContainerStyle=paddingRight:40
/>

【讨论】:

【参考方案9】:

我在我们的 android + iOS React Native 混合应用程序中看到了同样的问题。我们将 FlatList 组件嵌入到 Android 的 Fragment 中的原生 UI 中,我们无法滚动到列表中的最后一项,即使滚动指示器会显示还有更多要滚动,但 ScrollView 根本不会滚动。我尝试了使用包装 &lt;View style=flex:1&gt; 包装 FlatList 以及在 FlatList 上使用 contentContainerStyle=flexGrow:1 的所有组合,但均未成功。进一步追查发现 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)
    

【讨论】:

【参考方案10】:

利用平面列表中的 contentContainerStyle 属性 &lt;FlatList contentContainerStyle=paddingBottom: 10 /&gt;

【讨论】:

【参考方案11】:

只需使用 flex:1 将其包裹在视图中

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

另外,请注意,包含 Flatlist 的“View”的每个父级也必须是 Flex 为 1 的 View。否则,您的 flatlist 将不可见。

【讨论】:

“另外,请注意,包含 Flatlist 的“视图”的每个父级也必须是 Flex 为 1 的视图。否则,您的平面列表将不可见。 ....非常有用的评论!谢谢。 它就像一个魅力!虽然不知道为什么 flex=1 解决了这个问题【参考方案12】:

flex: 1 添加到包含Flatlist 组件的View 标签。

就我而言,

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;

【讨论】:

当我这样做时,我的列表将不再可见。 如果您的列表不可见,则可能是父视图不灵活:1,您必须找到未扩展的父视图。 &lt;FlatList style=flex: 1 也为我工作,没有任何父母 &lt;View/&gt;。不过必须将 flex: 1 添加到主容器视图。【参考方案13】:

对于 IOS 问题,您可以应用一些 IOS 特定的道具:

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

在我的情况下,使用contentContainerStyle 填充的解决方案似乎并不是解决安全区域 IOS 问题的最佳整体。

【讨论】:

我的平面列表处于固定高度的模式中。在我的情况下,这比任何解决方案都有效。【参考方案14】:

使用 FlatList 的 contentContainerStyle 属性

<FlatList contentContainerStyle= paddingBottom: 20 />

【讨论】:

以上是关于React Native FlatList 最后一项可见性问题的主要内容,如果未能解决你的问题,请参考以下文章

react-native ScrollView 嵌套 FlatList滚动

React Native FlatList 没有滚动到结束

在 React Native 中动态添加项目到 FlatList

React Native之FlatList组件(一)

React Native:在Modal中显示FlatList数据

React Native flatlist,无法从一开始就加载视图