当动画属性启动为false时,ReactNative ActivityIndi​​cator不显示

时间:2016-07-26 01:10:54

标签: react-native

我和本地人一起玩,并且有一种奇怪的行为。

当我尝试为Android显示 ActitvityIndi​​cator 时,将其动画属性设置为true,并且状态为showProgress的变量不起作用如果变量启动为false。

在下面的示例中,如果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});
    }
}

我在这里缺少什么?

10 个答案:

答案 0 :(得分:18)

这似乎是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 :(得分:3)

这是组件活动指标的React-Native的错误。 我不确定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"/>

答案 2 :(得分:2)

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

轻松解决我们的问题,因为此组件使用类似的方式显示或隐藏具有属性visible的活动。

答案 3 :(得分:2)

我尝试了一种不同的方法,我认为这是一种更多的反应方式&#34;解决问题。因此,opacity解决方案的问题在于,如果您只是将其设置为0,它仍然是动画,因此它不是您应用程序性能的最佳解决方案。

我创建了一个名为<Loading/>的分离组件,这里是代码:

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原生组件。

答案 4 :(得分:1)

我发现有效解决该问题的另一种方法是:

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

答案 5 :(得分:1)

我遇到的唯一问题是,由于我的屏幕背景,在Android中它不可见。我通过仅将颜色道具更改为我知道应该在背景中突出显示的内容来进行修复:

<ActivityIndicator color={theme.secondary.color} />

答案 6 :(得分:0)

我错了所有这个问题。我没有把execute()放在视图的中心。所以它位于一个视图的顶部,由一个讨人喜欢的酒吧覆盖。下面的代码是正确的。希望这可以帮助你。

ActivityIndeicator

答案 7 :(得分:0)

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

结帐:

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

答案 8 :(得分:0)

对于我来说,对于react本机版本0.59.10来说,size属性类型在Android和iOS上是不同的,因此我必须进行如下所示的Platform检查,然后才能起作用。

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

答案 9 :(得分:0)

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

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

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