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
组件的底部添加填充。 <FlatList style= paddingBottom: 20 ... />
嘿,这是解决问题的唯一方法吗?添加一个 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】:为<FlatList>
内容容器设置底部填充:
<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】:你可以试试这个解决方案
对于Vertical
FlatList
:
<FlatList
ListFooterComponent=<View />
ListFooterComponentStyle=height:200
/>
对于Horizontal
FlatList
:
<FlatList
contentContainerStyle=paddingRight:40
/>
【讨论】:
【参考方案9】:我在我们的 android + iOS React Native 混合应用程序中看到了同样的问题。我们将 FlatList 组件嵌入到 Android 的 Fragment 中的原生 UI 中,我们无法滚动到列表中的最后一项,即使滚动指示器会显示还有更多要滚动,但 ScrollView 根本不会滚动。我尝试了使用包装 <View style=flex:1>
包装 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 属性
<FlatList contentContainerStyle=paddingBottom: 10 />
【讨论】:
【参考方案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,您必须找到未扩展的父视图。<FlatList style=flex: 1
也为我工作,没有任何父母 <View/>
。不过必须将 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