Как показать прогресс загрузки или счетчик в центре экрана с помощью React Native?
Я разрабатываю приложение React Native.
Мне удалось решить все проблемы самостоятельно, но это исключение. Я собираюсь загрузить еще один экран с нижним навигатором вкладок.
Например, после входа пользователя в приложение он должен отобразить главный домашний экран с множеством изображений и множеством эффектов таблиц стилей, значков. Из-за этого после подтверждения входа в систему (я имею в виду после предупреждения о подтверждении входа в систему) главный домашний экран появляется через несколько секунд.
Поэтому я хочу показать какой-нибудь счетчик на экране входа в систему при загрузке основного домашнего экрана в фоновом режиме, и когда он будет готов к показу, стереть счетчик и показать главный домашний экран. Как я могу это сделать?
Мой нижний навигатор вкладок был просто создан с помощью createBottomTabNavigator()
метод.
7 ответов
Итак, в вашем случае вы можете сделать несколько вещей
- Вы можете использовать React Native Activity Indicator -> View
- Вы можете использовать Overlay Library -> react-native-loading-spinner-overlay -> View GitHub
- Если вам нравится делать загрузку как facebook / instagram ->, тогда используйте response-native-easy-content-loader -> View GitHub
Предположим, вы используете индикатор активности React Native:
import { ActivityIndicator } from "react-native";
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true
};
}
//Get Home Screen Data API Action
componentDidMount() {
this.loadAPI(); // Call home screen get data API function
}
//Login API Function
loadAPI = () => {
this.setState({ isLoading: true }); // Once You Call the API Action loading will be true
fetch(API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json"
}
})
.then(response => response.json())
.then(responseText => {
// You can do anything accroding to your API response
this.setState({ isLoading: false }); // After getting response make loading to false
})
.catch(error => {});
};
render() {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
{this.state.isLoading && <ActivityIndicator color={"#fff"} />}
</View>
);
}
}
- Если вы хотите скрыть все представление до завершения загрузки, как изображения, вы можете использовать пользовательскую библиотеку вместо индикатора активности.
Я создал свой собственный компонент загрузчика. Используя это, вы можете отображать встроенный в ActivityIndicator или пользовательский загрузчик GIF изображение с наложением.
Loader.js
import React, { Component } from 'react';
import {
StyleSheet,
View,
Modal,
Image,
ActivityIndicator
} from 'react-native';
import Colors from '../../config/Colors';
class Loader extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: this.props.isLoading
}
}
static getDerivedStateFromProps(nextProps) {
return {
isLoading: nextProps.isLoading
};
}
render() {
return (
<Modal
transparent={true}
animationType={'none'}
visible={this.state.isLoading}
style={{ zIndex: 1100 }}
onRequestClose={() => { }}>
<View style={styles.modalBackground}>
<View style={styles.activityIndicatorWrapper}>
<ActivityIndicator animating={this.state.loading} color={Colors.primary} />
{/* If you want to image set source here */}
{/* <Image
source={require('../assets/images/loader.gif')}
style={{ height: 80, width: 80 }}
resizeMode="contain"
resizeMethod="resize"
/> */}
</View>
</View>
</Modal>
)
}
}
const styles = StyleSheet.create({
modalBackground: {
flex: 1,
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'space-around',
backgroundColor: '#rgba(0, 0, 0, 0.5)',
zIndex: 1000
},
activityIndicatorWrapper: {
backgroundColor: '#FFFFFF',
height: 100,
width: 100,
borderRadius: 10,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-around'
}
});
export default Loader
Теперь вы можете использовать его, когда вам нужно отобразить индикатор загрузки, как показано ниже:
<Loader isLoading={this.state.isLoading} />
Вы должны использовать ActivityIndicator, вы можете загрузить этот индикатор активности перед получением данных с сервера, вы должны проверить приведенный ниже код, надеюсь, вы поймете
import React, {useEffect, useState} from 'react';
import {ActivityIndicator, View, Dimensions} from 'react-native';
import HomeScreen from './Home';
const DataViewer = () => {
const [data, setData] = useState([]);
const {height, width} = Dimensions.get('window');
useEffect(() => {
fetch('http://example.com/movies.json')
.then(response => {
return response.json();
})
.then(myJson => {
setData(myJson);
});
});
return data.length > 0 ? (
<HomeScreen data={data} />
) : (
<View
style={{justifyContent: 'center', alignItems: 'center', height, width}}>
<ActivityIndicator size="large" color="#0000ff" />
</View>
);
};
export default DataViewer;
import { ActivityIndicator } from 'react-native';
export default class LoginScreen extends Component {
constructor(props) {
super(props);
this.state = {
spinner : true
}
}
render() {
return (
<View style={{flex : 1, justifyContent: 'center', alignItems: 'center',}}>
{
this.state.spinner &&
<ActivityIndicator color={'#fff'} />
}
</View>
)
}
}
Таким образом, вы можете показать SPinner для предположения, когда вам нужно загрузить API или что-то еще, и когда вы получите ответ api, вы можете установить для значения загрузки счетчика значение false.
Например:
import {View, ActivityIndicator } from 'react-native';
export default class MainScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
spinner : true
}
}
componentDidMount(){
this.loadApi();
}
loadApi = async() => {
let result = axios.get('url').then((data) =>{
this.setState({spinner:false});
}
).catch((err) => this.setState({spinner:false})
}
render() {
return (
<View style={{flex : 1, justifyContent: 'center', alignItems: 'center',}}>
{
this.state.spinner? <ActivityIndicator color={'#fff'} />:<View><Text>Data loaded</Text></View>
}
</View>
)
}
}
Вы можете использовать индикатор активности в качестве анимации загрузки по умолчанию. Но вы также можете использовать файлы Lottie для реализации пользовательской анимации экрана загрузки в вашем проекте, установивnpm i lottie-react-native
илиyarn add lottie-react-native
Другой вариант — использовать простой вращающийся значок для отображения прогресса. Вы можете поместить его в представление и переместить в центр страницы или, как в моем случае, поместить его внутри кнопки, чтобы показать пользователю некоторую активность.
FontAwesomeSpin.tsx
import React, { Component } from 'react';
import { Animated, Easing } from 'react-native';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
interface FontAwesomeSpinProps {
enabled: boolean;
color?: string;
size?: number;
}
class FontAwesomeSpin extends Component<FontAwesomeSpinProps> {
spinValue = new Animated.Value(0);
_isMounted = false;
componentDidMount() {
this._isMounted = true;
if (this.props.enabled) {
this.spin();
}
}
componentDidUpdate(prevProps: FontAwesomeSpinProps) {
if (this.props.enabled && !prevProps.enabled) {
this.spinValue.setValue(0);
this.spin();
}
}
componentWillUnmount() {
this._isMounted = false;
}
spin = () => {
this.spinValue.setValue(0);
Animated.timing(this.spinValue, {
toValue: 1,
duration: 1000,
easing: Easing.linear,
useNativeDriver: true,
}).start(() => {
if (this._isMounted && this.props.enabled) {
this.spin();
}
});
};
render() {
const { enabled: loading, color, size = 24 } = this.props;
if (!loading) {
return null;
}
const rotate = this.spinValue.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] });
return (
<Animated.View
style={{
width: size,
height: size,
alignItems: 'center',
justifyContent: 'center',
overflow: 'hidden',
transform: [{ rotate }],
}}
>
<FontAwesomeIcon icon="spinner" color={color} size={size} />
</Animated.View>
);
}
}
export default FontAwesomeSpin;
Вы можете использовать его следующим образом:
<FontAwesomeSpin enabled={loading} size={32} style={{ marginTop: 20 }} />