我在世博会的 React Native 中使用了一个非常简单的 GiftedChat 组件,这里的问题是当我第一次打开键盘时效果很好,但第二次我按下 textInput 但键盘没有出现,我'我使用 android 5 的模拟器和 android 7 的设备。不适用于任何
import { useState, useLayoutEffect, useCallback } from 'react'
import { TouchableOpacity } from 'react-native'
import { GiftedChat } from 'react-native-gifted-chat'
import {
collection,
addDoc,
orderBy,
query,
onSnapshot
} from 'firebase/firestore'
import { signOut } from 'firebase/auth'
import { auth, database } from '../config/firebase'
import { useNavigation } from '@react-navigation/native'
import { AntDesign } from '@expo/vector-icons'
import colors from '../colors'
export default function Chat() {
const [messages, setMessages] = useState([])
const navigation = useNavigation()
const onSignOut = () => {
signOut(auth)
.catch(err => console.log('Error logging out: ', err.message))
}
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
style={{
marginRight: 10
}}
onPress={onSignOut}
>
<AntDesign
name='logout'
size={24}
color={colors.gray}
style={{
marginRight: 10
}}
/>
</TouchableOpacity>
)
})
}, [navigation])
useLayoutEffect(() => {
const collectionRef = collection(database, 'chats')
const q = query(collectionRef, orderBy('createdAt', 'desc'));
const unsubscribe = onSnapshot(q, snapshot => {
setMessages(
snapshot.docs.map(doc => ({
_id: doc.data()._id,
createdAt: doc.data().createdAt.toDate(),
user: doc.data().user,
text: doc.data().text
}))
)
})
return unsubscribe
}, [])
const onSend = useCallback((messages = []) => {
setMessages(previewMessages => GiftedChat.append(previewMessages, messages))
const { _id, createdAt, text, user } = messages[0]
addDoc(collection(database, 'chats'), {
_id,
createdAt,
text,
user,
})
}, [])
return (
<>
<GiftedChat
messages={messages}
showAvatarForEveryMessage={false}
showUserAvatar={true}
onSend={message => onSend(message)}
messagesContainerStyle={{
backgroundColor: '#fff'
}}
user={{
_id: auth?.currentUser?.email,
avatar: 'https://placeimg.com/140/140/any'
}}
/>
</>
)
}
问题是,如果您使用虚拟 Android 按钮关闭键盘,则
TextInput
的 GiftedChat
(实际上通常是 TextInput
)永远不会失去焦点。因此,如果您只是修改 TextInput,则键盘不会再次打开。如果您触摸外部,然后再次触摸内部,您会注意到键盘再次打开。这应该是任何 TextInput
的正常行为,甚至可能是用户所期望的(我们可以通过按相同的按钮再次打开键盘)。
但是,您也可以尝试以编程方式处理此问题。
GiftedChat
组件提供了一个功能,允许您以编程方式再次重新聚焦 TextInput
。它被称为 focusTextInput()
并且它
打开键盘并聚焦文本输入框
const ref = useRef(null)
<GiftedChat
…
ref={ref}
/>
然后,拨打
ref.focusTextInput()
。然后,我们可以将 GiftedChat
组件包装在 Pressable
中,并在 onPress
函数中触发它。
const ref = useRef(null)
<Pressable onPress={() => ref.focusTextInput()}
<GiftedChat
…
ref={ref}
/>
</Pressable>
找到解决方案:只需关闭键盘即可失去焦点:
useEffect(() => {
const keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
Keyboard.dismiss,
);
return () => {
keyboardDidHideListener.remove();
};
}, []);