我有一个包含少量表单元素和一个按钮的视图(TouchableHighlight)。单击该按钮时,活动指示器应显示为现有视图的叠加层。活动指示器应在页面中居中,现有视图应略微模糊以指示叠加。我尝试了不同的选择,但无法让它发挥作用。
render() {
const { username, password } = this.state;
return (
<View style={styles.container}>
<View style={styles.group}>
<Text style={styles.text}>Username:</Text>
<TextInput
style={styles.input}
onChangeText={this.handleUserNameChange.bind(this)}
value={username}
underlineColorAndroid="transparent"
/>
</View>
<View style={styles.group}>
<Text style={styles.text}>Password:</Text>
<TextInput
style={styles.input}
secureTextEntry={true}
onChangeText={this.handlePasswordChange.bind(this)}
value={password}
underlineColorAndroid="transparent"
/>
</View>
<TouchableHighlight
style={styles.button}
onPress={this.handleLogin.bind(this)}>
<Text style={styles.buttonText}>Logon</Text>
</TouchableHighlight>
</View>
);
}
现有风格:
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: '#F5FCFF',
marginTop: 60
},
group: {
alignItems: 'flex-start',
padding: 10
},
input: {
width: 150,
padding: 2,
paddingLeft: 5,
borderColor: 'gray',
borderWidth: 1
},
text: {
padding: 0
},
button: {
width: 150,
backgroundColor: '#2299F2',
padding: 15,
marginTop: 20,
borderRadius: 5
},
buttonText: {
textAlign: 'center',
color: '#fff',
fontSize: 24
},
});
我需要在上面的View中使用ActivityIndicator,覆盖视图,并使ActivityIndicator居中。
答案 0 :(得分:81)
为了实现这一点,您需要absolute
定位它,并在应该位于叠加层下方的元素之后将其渲染为:
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
}
&#13;
然后根据加载状态,有条件地将其组合成render
方法。我将假设this.handleLogin
已设置某种加载状态。
确保它最后呈现,因此优先。
...
{this.state.loading &&
<View style={styles.loading}>
<ActivityIndicator size='large' />
</View>
}
&#13;
答案 1 :(得分:16)
以下是使用create react native app的完整示例。
import React from 'react';
import {StyleSheet, ActivityIndicator, View} from "react-native";
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {}
render() {
return (
<View
style={{flex: 1}}
>
//Add other content here
{this.state.loading &&
<View style={styles.loading}>
<ActivityIndicator/>
</View>
}
</View>
);
}
}
showLoading() {
this.setState({loading: true})
}
hideLoading() {
this.setState({loading: false})
}
const styles = StyleSheet.create({
loading: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
opacity: 0.5,
backgroundColor: 'black',
justifyContent: 'center',
alignItems: 'center'
}
})
答案 2 :(得分:1)
您还可以利用活动指示器组件,还可以利用Sanaur建议的模式功能来构建漂亮的覆盖图。
例如,您可以使用以下功能组件。您可以通过show
道具来控制它的可见性,从而可以绑定到屏幕上的状态。
一个可以满足您的需求的示例。
const ModalActivityIndicator = props => {
const {
show = false,
color = "black",
backgroundColor = "white",
dimLights = 0.6,
loadingMessage = "Doing stuff ..."
} = props;
return (
<Modal transparent={true} animationType="none" visible={show}>
<View
style={{
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: `rgba(0,0,0,${dimLights})`
}}
>
<View
style={{
padding: 13,
backgroundColor: `${backgroundColor}`,
borderRadius: 13
}}
>
<ActivityIndicator animating={show} color={color} size="large" />
<Text style={{ color: `${color}` }}>{loadingMessage}</Text>
</View>
</View>
</Modal>
);
};
在屏幕上,在渲染的返回处,只需将其作为子项添加到那里(请忽略其余的代码,我将其放在此处作为上下文)。
return (
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss();
}}
>
<View style={{ padding: 13, flex: 1}}>
<ModalActivityIndicator show={screenIsWaiting} />
<View
style={{
例如screenIsWaiting
只是一个状态
const [screenIsWaiting, setScreenIsWaiting] = useState(false);
要对其进行测试,您可以在某处添加按钮,
<Button
title="TestButton"
onPress={async () => {
setScreenIsWaiting(true);
await sleep(5000);
setScreenIsWaiting(false);
...
}}
/>
其中睡眠是定义为的功能
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
我在另一篇文章中发现了关于stackoverflow的sleep()想法。
您当然也可以定义
<ModalActivityIndicator show={screenIsWaiting} ... />
仅在应用程序的根组件中一次,并通过全局状态容器(如redux)触发它的显示和道具。
答案 3 :(得分:1)
根据加载情况添加
setup.exe
答案 4 :(得分:1)
您可以使用StyleSheet.absoluteFill
来缩短代码。
将此添加到渲染中:
<View style={styles.container}>
//... other code here
{this.state.loading && <View
style={{
...StyleSheet.absoluteFill,
justifyContent: 'center',
alignItems: 'center',
}}>
<ActivityIndicator />
</View>}
</View>
改进:
您还可以创建一个Loading组件:
Loading.js
import React from 'react';
import {View, ActivityIndicator, StyleSheet} from 'react-native';
export const Loading = ({theme = 'white', size = 'large'}) => {
const color = theme === 'white' ? '#00bdcd' : '#fff';
return (
<View
style={{
...StyleSheet.absoluteFill,
justifyContent: 'center',
alignItems: 'center',
}}>
<ActivityIndicator size={size} color={color} />
</View>
);
};
然后在任何需要的地方使用它
<View style={styles.container}>
//... other code here
// remember to import Loading component
{this.state.loading && <Loading />}
</View>
答案 5 :(得分:0)
我想您应该使用Modal覆盖活动指示器。以下是一个示例:
<Modal
transparent={true}
animationType={'none'}
visible={loading}
onRequestClose={() => {console.log('close modal')}}>
<View style={styles.modalBackground}>
<View style={styles.activityIndicatorWrapper}>
<ActivityIndicator
animating={loading} />
</View>
</View>
</Modal>
答案 6 :(得分:0)
此react-native-loading-spinner-overlay有一个可用的库。 您可以简单地使用
进行安装npm install react-native-loading-spinner-overlay --save
,并可以使用
导入您的项目import Spinner from 'react-native-loading-spinner-overlay';
这里是使用方法
<Spinner
//visibility of Overlay Loading Spinner
visible={this.state.loading}
//Text with the Spinner
textContent={'Loading...'}
//Text style of the Spinner Text
textStyle={styles.spinnerTextStyle}
/>
答案 7 :(得分:0)
在“活动指标”视图中设置
位置:“绝对”, 左:0, 右:0, 上:0, 底部:0, alignItems:'中心', justifyContent:“中心”
答案 8 :(得分:0)
第 1 步: 为微调器创建组件:
export const OverlaySpinner = () => {
return (
<View style={styles.spinnerView}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
};
第 2 步:
为微调视图创建样式(使用 zIndex 非常重要,以确保视图覆盖屏幕上的所有内容):
spinnerView: {
position: "absolute",
zIndex: 1,
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#F5FCFF88",
},
第 3 步:
为旋转组件设置初始状态:
const [showSpinner, setshowSpinner] = useState(true);
第 4 步:
使用组件不要忘记导入(提交时不要忘记关闭键盘)
{showSpinner && <OverlaySpinner />}