如何制作带有动画的自定义单选按钮?反应本机

时间:2019-06-25 14:48:45

标签: react-native react-native-flatlist react-animated

我在React Native中创建了一个自定义单选按钮。以下是我的代码的链接。

https://gist.github.com/shubh007-dev/0d8a0ca4d6f7d1530f3e28d223f9199e

我想要的是在按下单选按钮时对其进行动画处理,就像在此库中一样-https://www.npmjs.com/package/react-native-simple-radio-button

我第一次可以对单选按钮进行动画处理,但是当我按下另一个单选按钮时,动画不会发生。

(该问题的另一种方法)如何确保每个单选按钮的Animated值都不同?

2 个答案:

答案 0 :(得分:1)

您必须为收音机创建一个自定义组件,或者为x个单选按钮使用x动画变量。

现在,使x个按钮的x变量不是一种有效的解决方案,但是如果您只有几个按钮,则可以使用它。

您制作了一个自定义组件,该组件呈现了一个平面列表,这就是问题所在;无法在用于渲染按钮的同一组件中分别为按钮设置动画。

您应该拆分代码,并使单选按钮成为组件本身。 那样的东西(虽然没有测试,但是那样就可以了):

export class RadioButton extends Component {
  constructor(props) {
    super(props);
    this.state = {
      radioSelected: this.props.selectedItemId,
    };
  }

  radioClick = id => {
    this.setState({ radioSelected: id });
    this.props.onChange(id);
  }

  renderRadioButton = item => {
    const { radioSelected } = this.state;
    const { labelLeftStyle, labelRightStyle, labelOnRight } = this.props;
    return (
      <AnimatedRadio
        {...item}
        isSelected={item.id === radioSelected}
        labelLeftStyle={labelLeftStyle}
        labelRightStyle={labelRightStyle}
        labelOnRight={labelOnRight}
        radioClick={this.radioClick}
      />
    );
  };

  render() {
    return (
      <FlatList
        data={this.props.radioOptions}
        extraData={this.state}
        renderItem={({ item }) => this.renderRadioButton(item)}
        keyExtractor={(item, index) => index.toString()}
      />
    );
  }
}

export class AnimatedRadio extends Component {
  springValue = new Animated.Value(1.1);

  onRadioClick = id => () => {
    const { radioClick } = this.props;
    radioClick(id);
    this.spring();
  };

  spring = () => {
    Animated.spring(this.springValue, {
      toValue: 0.95,
      friction: 2,
      tension: 15,
    }).start();
  };

  render() {
    const {
      id,
      label,
      labelLeftStyle,
      labelRightStyle,
      labelOnRight,
      isSelected,
    } = this.props;
    return (
      <View key={id} style={STYLES.radioContainerView}>
        <TouchableOpacity
          style={STYLES.radioButtonDirectionStyle}
          onPress={this.onRadioClick(id)}
        >
          {labelOnLeft == true ? (
            <Text style={[labelLeftStyle]}>{label}</Text>
          ) : null}

          <View
            style={[isSelected ? STYLES.selectedView : STYLES.unselectedView]}
          >
            {isSelected ? (
              <Animated.View
                style={[
                  STYLES.radioSelected,
                  { transform: [{ scale: this.springValue }] },
                ]}
              />
            ) : null}
          </View>

          {labelOnRight == true ? (
            <Text style={[labelRightStyle]}>{label}</Text>
          ) : null}
        </TouchableOpacity>
      </View>
    );
  }
}

通过这种方式,每个组件收音机都将具有自己的动画值,并且不会干扰其他按钮。

答案 1 :(得分:0)

我使用LayoutAnimation.configureNext({ duration: 300, create: { type: 'linear', property: 'scaleXY', }, update: { type: 'spring', springDamping: 0.4, property: 'opacity', }, delete: { type: 'easeOut', property: 'opacity', }, }); 做到了,如下所示。

UPDATE
  build
SET
  `datetime` = CONCAT('2019', RIGHT(`datetime`, 15))
WHERE
  LEFT(`datetime`, 4) = '2015'