How do I overlay ActivityIndicator in react-native?

前端 未结 8 2306
没有蜡笔的小新
没有蜡笔的小新 2020-12-13 05:55

I have a View with few form elements and a button (TouchableHighlight). On clicking the button, an Activity Indicator should be shown as an overlay to the existing view. The

相关标签:
8条回答
  • 2020-12-13 06:30

    For this to work, you'd need to absolute position it, and render it after the elements that should be underneath the overlay:

      loading: {
        position: 'absolute',
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
        alignItems: 'center',
        justifyContent: 'center'
      }

    Then simply compose it into the render method conditionally, based on a loading state. I am going to assume this.handleLogin sets some sort of loading state already.

    Make sure it's rendered last so it takes precedence.

    ...
    {this.state.loading &&
        <View style={styles.loading}>
          <ActivityIndicator size='large' />
        </View>
    }

    0 讨论(0)
  • 2020-12-13 06:31

    You can build a nice overlay using the activity indicator component by also leveraging the modal capabilities like Sanaur suggests.

    For example you can use the below functional component. You can control it's visibility through the show prop that you can tie to a state in your screen.

    An example that you can adapt to your needs.

    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>
      );
    };
    

    and in your screen, in the render's return, just add it there as a child (please ignore the rest of the code, I put it there for context).

    return (
    <TouchableWithoutFeedback
      onPress={() => {
        Keyboard.dismiss();
      }}
    >
      <View style={{ padding: 13, flex: 1}}>
        <ModalActivityIndicator show={screenIsWaiting} />
        <View
          style={{
    

    where screenIsWaiting is just a state, for example

      const [screenIsWaiting, setScreenIsWaiting] = useState(false);
    

    To test it you can add a button somewhere,

      <Button
        title="TestButton"
        onPress={async () => {
          setScreenIsWaiting(true);
          await sleep(5000);
          setScreenIsWaiting(false);
          ...
        }}
      />
    

    where sleep is a function defined as

    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    

    I found the sleep() idea on stackoverflow on another post.

    You can of course also define the

    <ModalActivityIndicator show={screenIsWaiting} ... />
    

    only once in your App's root component and trigger it's display and props via a global state container like redux.

    0 讨论(0)
提交回复
热议问题