Как бы я включил анимацию во время выполнения в React Native, используя Lottie?

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

К сожалению, кроме iOS, я не могу найти никакой документации по переключению анимации на кнопку в React Native. Любые идеи были бы хорошы.

Вот компонент:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
    StyleSheet,
    TouchableOpacity
} from 'react-native';
import _ from 'lodash';

import { connect } from 'react-redux';
import { toggleSaved } from '../../actions';
import Animation from 'lottie-react-native';

import onAnimation from '../animations/heart_On.json';
import offAnimation from '../animations/heart_Off.json';

class SaveButton extends Component {
    isSaved = () => {
        let item = this.props.item;
        if (_.find(this.props.saved, function(i) { return i.type == item.type && i.id == item.id; })) {
            return true;
        } else {
            return false;
        }
    }

    toggleSaved = (saved, item) => {
        const { dispatch } = this.props;
        dispatch(toggleSaved(saved, item));
        this.animation.play();
    }

    render() {
        return (
            <TouchableOpacity
                onPress={ () => this.toggleSaved(this.props.saved, this.props.item) }
            >
                <Animation
                    ref={ animation => {
                        this.animation = animation;
                    } }
                    style={ styles.icon }
                    loop={ false }
                    source={ this.isSaved() ? onAnimation: offAnimation }
                />
            </TouchableOpacity>
        );
    }
}

SaveButton.propTypes = {
    dispatch: PropTypes.func.isRequired,
    saved: PropTypes.array.isRequired,
    item: PropTypes.object.isRequired
};

const styles = StyleSheet.create({
    icon: {
        width: 30,
        height: 30,
        marginTop: 5,
        marginRight: 10
    }
});

function mapStateToProps(state) {
    const { saved } = state.saved;

    return {
        saved
    };
}

export default connect(mapStateToProps)(SaveButton);

1 ответ

Решение

Я бы предложил вам иметь два отдельных элемента анимации, а затем, в зависимости от состояния, показать или скрыть (и, конечно,.play()) их соответственно.

Итак (код наполовину псевдо, чтобы понять идею):

  • государственная опора как isSaved, который определяет, какая анимация в данный момент находится на сцене,
  • при сохранении (или удалении) переключите состояние, чтобы показать правильную анимацию, и вызовите this.refToCorrectAnimation.play(),

constructor(props) {
  super(props);
  this.state = {
    isSaved: false,
  };
}

isSavedVisible() {
  return (this.state.isSaved) ? { display: 'flex' } : { display: 'none' };
}

isRemovedVisible() {
  return (!this.state.isSaved) ? { display: 'flex' } : { display: 'none' };
}


toggleSaved(...) {
  if (this.state.isSaved) {
    this.isSavedAnimation.play();
  } else {
    this.isRemovedAnimation.play();
}

render() {
  return (
    <TouchableOpacity onPress={() => this.toggleSaved()} ...>
      <Animation style={this.isSavedVisible()} ref={(animation) = this.isSavedAnimation = animation} ... />
      <Animation style={this.isRemovedVisible()} ref={(animation) = this.isRemovedAnimation = animation} ... />
    </TouchableOpacity>
  )
}
Другие вопросы по тегам