gpt4 book ai didi

react-native - 组件挂载时如何在 React Native 中自动打开键盘?

转载 作者:行者123 更新时间:2023-12-03 13:54:45 26 4
gpt4 key购买 nike

我的页面只有一个 TextInput ,并且我已经传入了 autoFocus prop: autoFocus: true

<TextInput
style={styles.textInput}
placeholder="Quiz Deck Title"
autoFocus={true}
value={this.state.title}
onChangeText={(title) => this.controlledTextInput(title)}
/>

我试图避免的是要求用户在键盘弹出之前在 TextInput 框中“单击”。

但我也想让软键盘也自动打开(如果设备没有硬件键盘)。

有没有办法让 native react 发生这种情况?我正在为 ios 和 android 开发。

如果重要的话,我的页面是通过 TabNavigator 导航到的。
我提到这一点是因为对另一个类似的 SO 问题(见下文)的评论表明他们在使用 StackNavigator 到达他们的页面时遇到了类似的问题。

关于类似 SO 问题的说明:
How to open keyboard automatically in React Native? : 没有提供解决方案,其他人的评论和我的结果一样:输入被聚焦,但键盘没有自动打开。
Close/hide the Android Soft KeyboardAndroid: show soft keyboard automatically when focus is on an EditText :使用原生安卓代码(java),而不是响应原生代码(javascript)。

注意:我正在使用带有 android 23(推荐)的 android 模拟器 Nexus 6P 和带有 iPhone 6s 的 ios 模拟器进行开发,因为我没有物理设备。

编辑:添加请求的代码

NewDeck.js (我希望键盘自动弹出的 View ):

import React from 'react';
import { connect } from 'react-redux';
import { View, Text, TouchableOpacity,
TextInput, KeyboardAvoidingView,
StyleSheet, Platform,
} from 'react-native';

import StyledButton from '../components/StyledButton';

import { saveDeck } from '../store/decks/actionCreators';
import { getDeckList } from '../store/decks/selectors';
import { fetchDecks } from '../utils/api';
import { saveDeckTitle } from '../utils/api';
} from '../utils/colors';
import { titleCase, stripInvalidChars, makeStringUnique }
from '../utils/helpers';
import { white, gray, primaryColor, primaryColorDark, primaryColorLight,

class NewDeck extends React.Component {
state = {
title: '',
canSubmit: false,
}
componentDidMount () {
this.textInputRef.focus()
}
controlledTextInput(title){
title = titleCase(stripInvalidChars(title));
const canSubmit = this.isValidInput(title);
this.setState({ title, canSubmit });
}
isValidInput(text){
return text.trim() !== '';
}
onBlur(){
title = this.state.title.trim();
const unique = makeStringUnique(title, this.props.existingTitles);
this.setState({ title: unique });
}
onSubmit(){
let title = this.state.title.trim();
title = makeStringUnique(title, this.props.existingTitles)
saveDeckTitle(title)
this.props.navigation.navigate('Home');
}
render() {
return (
<View style={styles.container}>
<View style={[styles.cardContainer, {flex: 1}]}>
<Text style={styles.instructionsText}
>
Title for your New Quiz Deck
</Text>

<KeyboardAvoidingView {...keyboardAvoidingViewProps}>
<TextInput
style={styles.textInput}
placeholder="Quiz Deck Title"
value={this.state.title}
onChangeText={(title) => this.controlledTextInput(title)}
/* autoFocus={true} */
ref={ref => this.textInputRef = ref}
/>
</KeyboardAvoidingView>
</View>

<KeyboardAvoidingView
{...keyboardAvoidingViewProps}
style={[styles.buttonsContainer, styles.buttonContainer]}
>
<StyledButton
style={[styles.item, style={flex: 2}]}
onPress={() => this.onSubmit()}
disabled={!this.state.canSubmit}
>
<Text>
Submit
</Text>
</StyledButton>
</KeyboardAvoidingView>
</View>
);
}
}

const keyboardAvoidingViewProps = {
behavior: 'padding',
};

// ...styles definition here, - I posted it in a later code block, to minimize
// clutter, in the event that it is irrelevant to this issue

function mapStoreToProps(store){
const decks = getDeckList(store) || null;
// ensure titles are unique (better UX than if just make id unique)
const existingTitles = decks && decks.map(deck => {
return deck.title
}) || [];
return {
existingTitles,
}
}
export default connect(mapStoreToProps)(NewDeck);

TabNavigator StackNavigator 代码(在 App.js 中):

// ... the TabNavigator I'm using:
import { TabNavigator, StackNavigator } from 'react-navigation';

//... the class's render method, uses StackNavigator (as MainNavigation)
render(){
return (
<Provider store={createStore(rootReducer)}>
<View style={{flex:1}}>
<AppStatusBar
backgroundColor={primaryColor}
barStyle="light-content"
/>
<MainNavigation />
</View>
</Provider>
);
}
}

// ...
const Tabs = TabNavigator(
{
DeckList: {
screen: DeckList,
navigationOptions: {
tabBarLabel: 'Quiz Decks',
tabBarIcon: ({ tintColor }) => // icons only show in ios
<Ionicons name='ios-bookmarks' size={30} color={tintColor} />
},
},
NewDeck: {
screen: NewDeck,
navigationOptions: {
tabBarLabel: 'Create New Deck',
tabBarIcon: ({ tintColor }) => // icons only show in ios
<FontAwesome name='plus-square' size={30} color={tintColor} />
},
},
},
{
navigationOptions: {
// do-not-display page headers for Tab Navigation
header: null
},
tabBarOptions: {
// ios icon and text color; android text color
activeTintColor: Platform.OS === 'ios' ? primaryColor : white,
pressColor: white,
indicatorStyle: {
backgroundColor: primaryColorDark,
height: 3,
},
style: {
height: 56,
backgroundColor: Platform.OS === 'ios' ? white : primaryColor,
shadowColor: 'rgba(0, 0, 0, 0.24)',
shadowOffset: {
width: 0,
height: 3
},
shadowRadius: 6,
shadowOpacity: 1
}
}
}
);

//... StackNavigator uses TabNavigator (as Tabs)
const stackScreenNavigationOptions = {
headerTintColor: white,
headerStyle: {
backgroundColor: primaryColor,
}
};
const MainNavigation = StackNavigator(
// RouteConfigs: This is analogous to defining Routes in a web app
{
Home: {
screen: Tabs, // Which also loads the first Tab (DeckList)
},
Deck: {
screen: Deck,
navigationOptions: stackScreenNavigationOptions,
},
Quiz: {
screen: Quiz,
navigationOptions: stackScreenNavigationOptions,
},
NewDeck: {
screen: NewDeck,
navigationOptions: stackScreenNavigationOptions,
},
NewCard: {
screen: NewCard,
navigationOptions: stackScreenNavigationOptions,
},
},
);

这是 样式 的定义,用于 NewDeck.js

const styles = StyleSheet.create({
// CONTAINER styles
wrapper: {
// this was the previous container style
flex: 1,
backgroundColor: white,
alignItems: 'center',
justifyContent: 'center',
},
container: {
flex: 1,
backgroundColor: white,
alignItems: 'center',
justifyContent: 'space-between',

padding: 10,
paddingTop: 30,
paddingBottom: 5,
},
cardContainer: {
flex: 1,
justifyContent: 'flex-start',
alignSelf: 'stretch',
backgroundColor: '#fefefe',

padding: 20,
marginLeft: 30,
marginRight: 30,
marginTop: 10,
borderRadius: Platform.OS === 'ios' ? 20 : 10,

shadowRadius: 3,
shadowOpacity: 0.8,
shadowColor: 'rgba(0, 0, 0, 0.24)',
shadowOffset: {
width: 0,
height: 3,
},
marginBottom:20,
},
buttonsContainer: {
flex: 3,
alignSelf: 'stretch',
justifyContent: 'flex-start',
},
buttonContainer: {
justifyContent: 'center',
margin: 10,
},

// TEXT Styles
instructionsText: {
flex: 1,
fontSize: 20,
color: gray,

alignSelf: 'center',
textAlign: 'center',
},

// INPUTTEXT styles
textInput: {
fontSize: 27,
color: primaryColor,

alignSelf: 'stretch',
flexWrap: 'wrap',
textAlign: 'center',
marginTop: 10,
},
});

StyledButton.js (基本上, TouchableOpacity 具有特定于平台的样式,可在整个应用程序中普遍使用):

import React from 'react';
import { Text, TouchableOpacity, StyleSheet, Platform } from 'react-native';
import { white, gray, primaryColor, primaryColorLight, primaryColorDark} from '../utils/colors';

export default function TextButton({ children, onPress, customColor, disabled=false }) {
const disabledColor = disabled ? gray : null;
const backgroundColor = Platform.OS==='ios' ? white : disabledColor || customColor || primaryColorLight;
const borderColor = Platform.OS==='ios' ? disabledColor || customColor || primaryColorDark
const textColor = Platform.OS==='ios' ? disabledColor || customColor || primaryColor : white;
const btnStyle = Platform.OS==='ios' ? styles.iosBtn : styles.androidBtn;
const txtStyle = styles.txtDefault;
const btnColor = { backgroundColor, borderColor };
const txtColor = { color: textColor };

return (
<TouchableOpacity
onPress={onPress}
disabled={disabled}
style={[btnStyle, btnColor]}
>
<Text
style={[styles.txtDefault, txtColor]}
>
{children}
</Text>
</TouchableOpacity>
);
}

const styles = StyleSheet.create({
txtDefault: {
textAlign: 'center',
// because of bleeding of white text to colored background on android,
// enlarge text (or increase fontWeight) for better readability
fontSize: Platform.OS==='ios' ? 15 : 18,
padding: 10,
},
iosBtn: {
height: 45,
borderRadius: 7,
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
// ios only settings
borderColor: primaryColorDark,
borderWidth: 1,
borderRadius: 3,
paddingLeft: 25,
paddingRight: 25,
},
androidBtn: {
height: 45,
borderRadius: 5,
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
// android- only settings
// (padding accepts clicks, vs. margin === no-click zone)
padding: 20,
paddingLeft: 15,
paddingRight: 15,
},
});

// ios has white buttons with colored outlines and colored text
// android has colored buttons with white text
// Pass in a button color, or it defaults to the App's primary colors

最佳答案

只需将 ref 包裹在 timeout 内setTimeout(()=>{this.textInputRef.focus()},100)

关于react-native - 组件挂载时如何在 React Native 中自动打开键盘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49989515/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com