Как показать прогресс загрузки или счетчик в центре экрана с помощью React Native?

Я разрабатываю приложение React Native.

Мне удалось решить все проблемы самостоятельно, но это исключение. Я собираюсь загрузить еще один экран с нижним навигатором вкладок.

Например, после входа пользователя в приложение он должен отобразить главный домашний экран с множеством изображений и множеством эффектов таблиц стилей, значков. Из-за этого после подтверждения входа в систему (я имею в виду после предупреждения о подтверждении входа в систему) главный домашний экран появляется через несколько секунд.

Поэтому я хочу показать какой-нибудь счетчик на экране входа в систему при загрузке основного домашнего экрана в фоновом режиме, и когда он будет готов к показу, стереть счетчик и показать главный домашний экран. Как я могу это сделать?

Мой нижний навигатор вкладок был просто создан с помощью createBottomTabNavigator() метод.

7 ответов

Решение

Итак, в вашем случае вы можете сделать несколько вещей

  1. Вы можете использовать React Native Activity Indicator -> View
  2. Вы можете использовать Overlay Library -> react-native-loading-spinner-overlay -> View GitHub
  3. Если вам нравится делать загрузку как 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 }} />
Другие вопросы по тегам