Как я могу сделать этот пользовательский компонент кнопки многократно используемым для разных элементов управления? - PullRequest
0 голосов
/ 01 октября 2019

У меня есть этот пользовательский класс компонентов, который я применяю к своим React Native Buttons, и он имеет ожидаемое поведение масштабирования и уменьшения (добавление анимации для уменьшения и изменения размера), и это именно то поведение, которое мне нужно. Тем не менее, я хочу такую ​​же анимацию для других элементов управления в моем приложении, например, для карт. Мне было интересно, как я могу изменить этот класс, чтобы сделать его более расширяемым?

Вот мой код:

import React from "react";
import { StyleSheet, Text, TouchableWithoutFeedback, Animated} from "react-native";
import Colors from "./Colors";
import Fonts from "./Fonts";

export default class TouchableBounce extends React.Component {

  constructor(props) {
    super(props);

    this.handlePressIn = this.handlePressIn.bind(this);
    this.handlePressOut = this.handlePressOut.bind(this);

  }

  componentWillMount() {
    this.animatedValue = new Animated.Value(1);
  }

  handlePressIn() {
    Animated.spring(this.animatedValue, {
      toValue: .5
    }).start()
  }

  handlePressOut() {
    Animated.spring(this.animatedValue, {
      toValue: 1,
      friction: 5,
      tension: 40
    }).start()
  }

  render() {

    const animatedStyle = {
        transform: [{ scale: this.animatedValue}]
      }

    const {
        disabled,
        text,
        color,
        backgroundColor,
        style,
        showArrow,
        testID,
        buttonStyle

    } = this.props;

    return (
      <TouchableWithoutFeedback
        onPressIn={this.handlePressIn}
        onPressOut={this.handlePressOut}
        disabled={disabled}
        style={[styles.buttonContainer, style]}
        testID={testID || `button_${text}`}
      >
        <Animated.View
          style={[
            styles.button,
            disabled ? { opacity: 0.5 } : {},
            { backgroundColor },
            buttonStyle,
            animatedStyle
          ]}
        >
          <Text style={[styles.buttonText, { color }]}>{text.toUpperCase()}</Text>
          {showArrow && (
            <Text
              style={{
                fontSize: 20,
                fontWeight: "bold",
                color: "white",
                fontFamily: "system font",
                marginBottom: 1
              }}
            >
              {" "}
              →
            </Text>
          )}
        </Animated.View>
      </TouchableWithoutFeedback>
    );
  }
} 

TouchableBounce.defaultProps = {
  disabled : false,
  color : Colors.white,
  backgroundColor : Colors.mainAccent,
  style : {},
  showArrow : false,
  testID : "",
  buttonStyle : {}
}

const styles = StyleSheet.create({
  buttonContainer: {
    alignSelf: "stretch",
    marginTop: 35,
    marginBottom: 35
  },
  button: {
    borderRadius: 4,
    padding: 20,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center"
  },
  buttonText: {
    textAlign: "center",
    fontFamily: Fonts.montserratBold,
    fontSize: 16
  }
});

РЕДАКТИРОВАТЬ: У меня есть вопрос о том, где я должен внести изменения для вложения компонента. Внутри моей функции рендеринга дома есть этот фрагмент

const card = active ? (
      <ActiveCard purchase={active} />

    ) : (
      <InactiveCard />
    );

и внутри моего возвращения этого рендера есть этот фрагмент

{!this.props.foo && (
                <View>
                  <TouchableOpacity
                    testID={"TOUCHABLE_CARD"}
                    onPress={() => {
                      this.tapCard(active);
                    }}
                  >
                    {card}
                  </TouchableOpacity>
                </View>
              )}

Куда мне обернуть TouchableBounce? В обоих местах или в одном из этих мест?

1 Ответ

1 голос
/ 01 октября 2019

Попробуйте передать их как потомков TouchableBounce

<TouchableBounce>
  <CardView/>
</TouchableBounce>

В TouchableBounce отобразите их как

<TouchableWithoutFeedback
  onPressIn={this.handlePressIn}
  onPressOut={this.handlePressOut}
  disabled={disabled}
  style={[styles.buttonContainer, style]}
  testID={testID || `button_${text}`}
>
  <Animated.View
    style={[
      styles.button,
      disabled ? { opacity: 0.5 } : {},
      { backgroundColor },
      buttonStyle,
      animatedStyle
    ]}
  >
    {this.props.children}//Here is the cardview that you have sent
  </Animated.View>
</TouchableWithoutFeedback>

Редактировать:

Для ясного понимания я прилагаю рабочую демонстрацию Экспо демо

, а также официальные документы React.Children

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...