我尝试在类似于Whatsapp UI的React Native中创建聊天视图。
我无法绕过的是 - 如何做时间。以下是Whatsapp的外观:
请注意,时间本身不是一条全新的线,而是半条线。
在上一个评论的同时,您可以看到,如果文本足够长,则时间将被推送到新行。
我尝试了几件事:
使气泡相对,然后在时间元素上使用绝对定位。不幸的是,如果文本足够长,我的时间会与文本重叠。
制作bubble flexDirection:" row",然后在1个视图中显示文本,在另一个视图中显示时间。但是,当文本足够长时,我无法弄清楚如何强制换行"。
任何想法如何实现这一目标?
答案 0 :(得分:0)
我设法得到了我想要的东西。它与whatsapp不是100%相同,但足够好。
我有以下代码:
<View style={{
margin: 10, marginTop: 10, marginBottom: 0,
padding: 10, borderRadius: 5, paddingBottom: 10,
backgroundColor: cropType ? '#93D14C' : '#F1F0F5'
}}>
{this.renderContent(comment)}
<Text
style={[styles.muted,
{
color: constants.FJMUTEDLIGHT,
backgroundColor: 'transparent',
alignSelf: 'flex-end',
fontSize: 12,
marginBottom: -5,
marginTop: 2
}]}>{moment.utc(comment.created).local().format('HH:mm')}</Text>
</View>
renderContentHere()函数可以渲染Text,但它也可以渲染包含文本的复杂View。最初我想弄清楚文本有多少行并计算行的宽度。这似乎不可能使用React Native,因为Text节点上的onLayout属性只能告诉您元素的宽度和高度,但如果Text是2行或3行则不能。
所以我决定只测量包含注释的View,并确定它是否有一行或多行。如果它有一条线,我假设我可以把时间放在比正常情况稍高的位置。
这就是我最终做的事情:
<View style={{
margin: 10, marginTop: 10, marginBottom: 0,
padding: 10, borderRadius: 5, paddingBottom: 10,
backgroundColor: cropType ? '#93D14C' : '#F1F0F5'
}}>
<View style={this.state.oneLine ? {
// Since we don't know how long the one line is, just in case add 25px padding on the right
// this way even if we are dealing with a long line of text it won't end up over the time
paddingRight: 25
} : {}}
onLayout={(e) => {
let {height} = e.nativeEvent.layout
// if height is less than 30px, then we are dealing with a single line of content
if (height < 30) {
this.setState({'oneLine': true})
}
}}>
{this.renderContent(comment)}
</View>
<Text
style={[styles.muted,
{
color: constants.FJMUTEDLIGHT,
backgroundColor: 'transparent',
alignSelf: 'flex-end',
fontSize: 12,
marginBottom: -5,
// If one line, move the time up - there is enough space
marginTop: this.state.oneLine ? -10 : 2
}]}>{moment.utc(comment.created).local().format('HH:mm')}</Text>
</View>
如果我们只有一行,那么文本最终可能会落后于时间,这就是为什么我在25 px的文本上应用正确的填充。这会打破长线,我们最终得到这样的视图: