【问题标题】:ReactNative ActivityIndicator not showing when animating property initiate false动画属性启动时 ReactNative ActivityIndi​​cator 不显示 false
【发布时间】:2016-11-29 11:58:19
【问题描述】:

我正在玩 react native 并且有一个奇怪的行为。

当我尝试为 Android 显示 ActivityIndi​​cator 时,将其 animating 属性设置为 true 且状态为 showProgress 变量,如果该变量为开始是假的。

在下面的示例中,如果 ActivityIndi​​cator 动画属性开始为 true,则按钮使 ActivityIndi​​cator 隐藏或正确显示。

import React, { Component } from 'react';
import {
  Text,
  View,
  StyleSheet,
  TextInput,
  TouchableHighlight,
  ActivityIndicator
} from 'react-native';

export class Login extends Component {

    constructor(props) {
        super(props);

        this.state = {
            showProgress: true
        };
    }

    render() {
        return (
            <View>

                <TouchableHighlight onPress={this.progressOff.bind(this)}>
                    <Text>progressOff</Text>
                </TouchableHighlight>

                <TouchableHighlight onPress={this.progressOn.bind(this)}>
                    <Text>progressOn</Text>
                </TouchableHighlight>

                <ActivityIndicator animating={this.state.showProgress} size="large"/>
            </View>
        );
    }

    progressOff() {
        this.setState({showProgress: false}); 
    }

    progressOn() {
        this.setState({showProgress: true});
    }
}

但是如果我使用下面的代码,动画属性以 false 开头,那么使 ActivityIndi​​cator 出现的按钮不起作用:

import React, { Component } from 'react';
import {
  Text,
  View,
  StyleSheet,
  TextInput,
  TouchableHighlight,
  ActivityIndicator
} from 'react-native';

export class Login extends Component {

    constructor(props) {
        super(props);

        this.state = {
            showProgress: false
        };
    }

    render() {
        return (
            <View>

                <TouchableHighlight onPress={this.progressOff.bind(this)}>
                    <Text>progressOff</Text>
                </TouchableHighlight>

                <TouchableHighlight onPress={this.progressOn.bind(this)}>
                    <Text>progressOn</Text>
                </TouchableHighlight>

                <ActivityIndicator animating={this.state.showProgress} size="large"/>
            </View>
        );
    }

    progressOff() {
        this.setState({showProgress: false}); 
    }

    progressOn() {
        this.setState({showProgress: true});
    }
}

我在这里错过了什么?

【问题讨论】:

  • 是 ios 的吗? facebook.github.io/react-native/docs/… 。默认情况下,当动画为假时它会隐藏
  • 我遇到了同样的问题,无法正常工作。当状态为假时,我最终在视觉上隐藏了指示器 ({height:0})。

标签: javascript react-native


【解决方案1】:

这似乎是 React Native 中的一个错误。初始状态为showProgress: false 的代码适用于iOS,但不适用于Android。

如果您想关注进度,我已经在 github 上打开了一个问题: https://github.com/facebook/react-native/issues/9023

选项 1

我使用的解决方法是使用showProgress 变量来呈现与ActivityIndicator 完全不同的视图:

render() {
    if (this.state.showProgress) {
        return this.renderLoadingView();
    } else {
        return this.renderMainView();
    }
}

选项 2

还可以根据状态设置ActivityIndicator的不透明度:

render() {
    return (
        <View>

            <TouchableHighlight onPress={this.progressOff.bind(this)}>
                <Text>progressOff</Text>
            </TouchableHighlight>

            <TouchableHighlight onPress={this.progressOn.bind(this)}>
                <Text>progressOn</Text>
            </TouchableHighlight>

            <ActivityIndicator style={{opacity: this.state.showProgress ? 1.0 : 0.0}} animating={true} size="large"/>
        </View>
    );
}

但是,使用此方法时,微调器动画并不总是从同一位置开始。

【讨论】:

  • 选项 1 是使用 this.forceUpdate() 强制更新的方法
  • @HimalayanCoder 如果您将showProgress 变量存储在this.state 中,通过this.setState() 更改它会自动触发重新渲染。无需使用forceUpdate()
  • 我已将animating 设置为true,但仍然没有显示-_-"
  • {this.state.animating &&
【解决方案2】:

如果在你的项目中可以使用第三方组件,我推荐使用react-native-loading-spinner-overlay

轻松解决了我们的问题,因为该组件使用类似的方式显示或隐藏带有属性visible的Activity。

【讨论】:

    【解决方案3】:

    我完全搞错了这个问题。我没有将ActivityIndeicator 放在视图的中心。因此它位于视图的顶部,该视图被导航栏覆盖。下面的代码是正确的。希望这可以帮助你。

    <View style={{alignItems: 'center', justifyContent: 'center', flex: 1, backgroundColor: 'white'}}>
      <ActivityIndicator
        animating={true}
        style={
          {
            alignItems: 'center',
            justifyContent: 'center',
            opacity: this.state.loading ? 1 : 0
          }}
        size="large"
      />
    </View>
    

    【讨论】:

      【解决方案4】:

      快速修复使用条件渲染.. 保持动画:{true} 和只是可见和不可见的视图。

      结帐:

      https://kylewbanks.com/blog/how-to-conditionally-render-a-component-in-react-native

      【讨论】:

        【解决方案5】:

        这是 React-Native 组件 Activity Indicator 的 bug。 我不确定fb是否已经解决了,但你可以试试这个

         constructor(props) {
                super(props);
                this.state = {
                    opacity: 0
                };
            }
        

        使用 this.setState({opacity:1}) 显示它并在调用的函数中再次隐藏 this.setState({opacity:0})

        在你使用活动指示器的渲染中

         <ActivityIndicator
            animating={true}
            color="#ffffff"
            style={{height: 80, marginTop: 10, opacity: this.state.opacity }}
            size="large"/>
        

        【讨论】:

        • 智能解决方案!
        【解决方案6】:

        我发现无需太多代码即可有效解决该问题的另一种方法是:

        { this.state.showProgress &&
          <ActivityIndicator animating={true} size="large"/>
        }
        

        【讨论】:

          【解决方案7】:

          我尝试了一种不同的方法,我认为这是一种解决问题的更“反应式”的方法。所以,opacity 解决方案的问题是,如果你只是设置为 0,它仍然是一个动画,所以它不是你的应用程序性能的最佳解决方案。

          我创建了一个单独的组件,我称之为&lt;Loading/&gt;,代码如下:

          import { ActivityIndicator } from "react-native"
          import React from "react"
          import PropTypes from "prop-types"
          
          const Loading = (props) =>
              props.animating
                  ? <ActivityIndicator style={props.style} 
                         importantForAccessibility='auto' size={props.size} 
                               color={props.size} /> : null
          
          Loading.propTypes = {
              animating: PropTypes.bool.isRequired,
              style: PropTypes.oneOfType([PropTypes.style, PropTypes.object]),
          }
          
          export default Loading
          

          用法:

          <Loading animating={true} importantForAccessibility='auto' size="large" color="#A02BFF" style={styles.loading} />
          

          这样可以避免在不需要时创建动画,您将创建可以在ActivityIndicator issue 将来通过将其替换为原始 ActivityIndi​​cator 原生解决方案时轻松删除的分离组件零件。

          【讨论】:

            【解决方案8】:

            在我的情况下,对于 react native 版本 0.59.10 ,Android 和 iOS 的 size 属性类型是不同的,因此我必须进行如下平台检查并且它有效。

            <ActivityIndicator 
                            size={Platform.OS === "ios" ? 0 : "large"} //This platform check worked.
                            color={props.color} 
                            animating={props.animating}
                            style={props.style}
                            />
            

            【讨论】:

              【解决方案9】:

              我遇到的唯一问题是,在 Android 中它不可见,因为我的屏幕上有背景。我通过仅将颜色道具更改为我知道应该在背景中突出的东西来修复:

              &lt;ActivityIndicator color={theme.secondary.color} /&gt;

              【讨论】:

                【解决方案10】:

                animatingfalsetrue 的转换在 Android 上太慢了。但是您可以使用 key 属性强制重新渲染:

                <ActivityIndicator
                  key={`${props.animating}`}
                  animating={props.animating}
                />
                

                props.animatingfalse 更改为true 时,它们的键也会发生变化。这会强制重新渲染,这意味着使用animating = true 渲染一个新组件,这将立即启动您的微调器。

                【讨论】:

                  【解决方案11】:

                  如果您在 Android 上对其进行测试,原因之一可能是颜色属性。

                  一定要给 ActivityIndi​​cator 一个颜色。例如:

                  <ActivityIndicator size="large" color="#0000ff" />
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-06-10
                    • 2019-06-25
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-01-05
                    • 1970-01-01
                    相关资源
                    最近更新 更多