react-native - 在 TextInput 中实现 @mention
问题描述
如何在 react native 的 TextInput 中实现 @mention?
我已经尝试过这个react-native-mention但它不再被维护了。有很多样式问题和回调问题。
我想要的是在 TextInput 中显示自定义视图。像这样的东西。
在点击列表后,我想像这样显示:
到目前为止,我能够实现:
当我在 TextInput 中键入“@”时,用户列表会出现。
当我点击用户时,我会在 TextInput 中获得用户名
代码:
renderSuggestionsRow() {
return this.props.stackUsers.map((item, index) => {
return (
<TouchableOpacity key={`index-${index}`} onPress={() => this.onSuggestionTap(item.label)}>
<View style={styles.suggestionsRowContainer}>
<View style={styles.userIconBox}>
<Text style={styles.usernameInitials}>{!!item.label && item.label.substring(0, 2).toUpperCase()}</Text>
</View>
<View style={styles.userDetailsBox}>
<Text style={styles.displayNameText}>{item.label}</Text>
<Text style={styles.usernameText}>@{item.label}</Text>
</View>
</View>
</TouchableOpacity>
)
});
}
onSuggestionTap(username) {
this.setState({
comment: this.state.comment.slice(0, this.state.comment.indexOf('@')) + '#'+username,
active: false
});
}
handleChatText(value) {
if(value.includes('@')) {
if(value.match(/@/g).length > 0) {
this.setState({active: true});
}
} else {
this.setState({active: false});
}
this.setState({comment: value});
}
render() {
const {comments} = this.state;
return (
<View style={styles.container}>
{
this.state.active ?
<View style={{ marginLeft: 20}}>
{this.renderSuggestionsRow()}
</View> : null
}
<View style={{ height: 55}}/>
<View style={styles.inputContainer}>
<TextInput
style={styles.inputChat}
onChangeText={(value) => this.handleChatText(value)}
>
{comment}
</TextInput>
<TouchableOpacity style={styles.inputIcon} onPress={() => this.addComment()}>
<Icon type='FontAwesome' name='send-o' style={{fontSize: 16, color: '#FFF'}}/>
</TouchableOpacity>
</View>
</View>
);
}
解决方案
一种简单的解决方案是使用react-native-parsed-text。这是一个例子:
import * as React from "react";
import { Text, View, StyleSheet } from 'react-native';
import ParsedText from 'react-native-parsed-text';
const userNameRegEx = new RegExp(/@([\w\d.\-_]+)?/g);
export default class Example extends React.Component {
handleNamePress = (name) => {
alert("Pressed username " + name);
}
render() {
return (
<View style={styles.container}>
<ParsedText
style={styles.text}
parse={
[
{pattern: userNameRegEx, style: styles.username, onPress: this.handleNamePress},
]
}
childrenProps={{allowFontScaling: false}}
>
This is a text with @someone mentioned!
</ParsedText>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
text: {
color: 'black',
fontSize: 15,
},
username: {
color: 'white',
fontWeight: 'bold',
backgroundColor: "purple",
paddingHorizontal: 4,
paddingBottom: 2,
borderRadius: 4,
},
});
但是,此库不支持呈现自定义视图。上面的例子是通过纯样式实现的。如果您需要自定义视图,您需要自己实现一些东西。长期以来,不可能渲染嵌入在文本组件中的任意组件。然而,这已经改变了 afaik,我们可以做这样的事情:
<Text>Hello I am an example <View style={{ height: 25, width: 25, backgroundColor: "blue"}}></View> with an arbitrary view!</Text>
在此处查看两个代码示例:https ://snack.expo.io/@hannojg/restless-salsa
一个重要的注意事项:您可以在 中呈现ParsedText
或您自己的自定义组件的输出TextInput
,如下所示:
<TextInput
...
>
<ParsedText
...
>
{inputValue}
</ParsedText>
</TextInput>
推荐阅读
- c# - 递归中使用的前缀减量与减法
- postgresql - 基于postgres的气流网络服务器错误
- linux - 如何在 Linux 上捕获全屏运行的 3D 应用程序?
- c# - OnAppearing Xamarin.Forms 中的 PopModalAsync
- python - 通过使用用户信息和管理员信息从 pythonda 数据库连接登录?
- python - 使用转换计算数据框中的特定值和聚合结果
- sql - 基于有效性的 SQL 分组
- bitbucket - 检查您是否有权合并 bitbucket git repo 的多个项目
- java - BouncyCastle 验证抛出 java.lang.IllegalArgumentException:getInstance 中的未知对象:org.bouncycastle.asn1.DERNull
- json - 反应无法访问查询值