ReactNative ActivityIndicator не отображается, когда анимация свойства инициирует false
Я играю с реакцией на родной язык и получаю странное поведение.
Когда я пытаюсь показать ActitvityIndicator для Android, для его анимирующего свойства значение true с переменной showProgress
в состоянии, это не работает, если переменная запущена как false.
В приведенном ниже примере, если свойство анимации ActivityIndicator начинается с true, тогда кнопки делают ActivityIndicator скрытым или отображаются правильно.
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, кнопка, отображающая ActivityIndicator, не работает:
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});
}
}
Что мне здесь не хватает?
Ответы
Ответ 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>
);
}
Однако при использовании этого метода анимация spinner не всегда начинается с той же позиции.
Ответ 2
Это ошибка 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"/>
Ответ 3
Если в вашем проекте вы можете использовать сторонние компоненты, я рекомендую использовать реакцию-native-load-spinner-overlay
Легко решить наши проблемы, поскольку этот компонент использует аналогичный способ показать или скрыть Activity с помощью свойства visible
.
Ответ 4
Я попробовал другой подход, который, как мне кажется, более "реагирует" на решение проблем. Таким образом, проблема с решением по 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 будет решена в будущем, заменив его на исходный собственный компонент ActivityIndicator.
Ответ 5
Другой способ, который я нашел эффективным, чтобы обойти эту проблему без большого количества кода:
{ this.state.showProgress &&
<ActivityIndicator animating={true} size="large"/>
}
Ответ 6
У меня эта проблема была ошибкой. я не поставил 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>
Ответ 7
Быстрое исправление Использование условного рендеринга. Продолжайте анимацию: {true} и просто видимое и невидимое представление.
Оформить заказ:
https://kylewbanks.com/blog/how-to-conditionally-render-a-component-in-react-native
Ответ 8
В моем случае для реагирования на нативную версию 0.59.10 тип свойства size отличается для Android и iOS, поэтому для этого мне пришлось проверить платформу следующим образом, и это сработало.
<ActivityIndicator
size={Platform.OS === "ios" ? 0 : "large"} //This platform check worked.
color={props.color}
animating={props.animating}
style={props.style}
/>