react-nativeonclickimagebackground

Changing ImageBackground onClick


I have a view with an imageBackground. Under this, I have 3 buttons. I want that, when you click on one of the buttons the imageBackground change.

I wanted to use switch case with change of states each time but it didn't work. I'm a little bit lost... I post my code and if you have any idea, thanks a lot for your help !

    export default class Weight extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          bgWidth: "100%",
          bgHeight: 0,
          animalBg:'duck',
          stats: {
            total_weight_carried: 0,
          },
        };
      }
    
      setBackgroundDimensions = (real_width, real_height) => {
        let final_width = real_width;
        let final_height = real_height * (width * 100 / real_width) / 100;
    
        this.setState({
          bgWidth: "100%", // Force 100% for compatibility
          bgHeight: final_height
        });
    
        console.log(height, real_height, (width * 100 / real_width), final_height);
      };
    
      UNSAFE_componentWillMount() {
        // Image.getSize(bgStatsURL, (width, height) => {this.setBackgroundDimensions({width, height})});
        this.setBackgroundDimensions(1125, 1589);
      }
    
   duck = () => {
    return(
      <ImageBackground
      source={require('../../assets/images/stats/bg-stats-weight-duck.jpg')}
      style={{ flex: 1, width: this.state.bgWidth, height: this.state.bgHeight, marginVertical: 25}}
      imageStyle={{ resizeMode: "contain" }}
    >
      <View style={{zIndex: 1, flexDirection: "row", justifyContent: 'center', marginTop: 5}}>
        <Text style={styles.statText}>
          <AnimateNumber
            value={this.state.stats.total_weight_carried}
            countBy={(this.state.stats.total_weight_carried / 50).toFixed(0)}
            style={styles.statTextData}
          />{" "}
          {i18n.t("stats.unit.kg")}
        </Text>
      </View>
      <View style={[styles.row, { marginTop: 450, alignItems: 'center', justifyContent: 'center'}]}>
        <Text style={styles.statText}>x ducks</Text>
      </View>
    </ImageBackground>
    )
  }

  elephant = () => {
    return(
    <ImageBackground
      source={require('../../assets/images/stats/bg-stats-weight-elephant.jpg')}
      style={{ flex: 1, width: this.state.bgWidth, height: this.state.bgHeight, marginVertical: 25}}
      imageStyle={{ resizeMode: "contain" }}
    >
      <View style={{zIndex: 1, flexDirection: "row", justifyContent: 'center', marginTop: 5}}>
        <Text style={styles.statText}>
          <AnimateNumber
            value={this.state.stats.total_weight_carried}
            countBy={(this.state.stats.total_weight_carried / 50).toFixed(0)}
            style={styles.statTextData}
          />{" "}
          {i18n.t("stats.unit.kg")}
        </Text>
      </View>
      <View style={[styles.row, { marginTop: 450, alignItems: 'center', justifyContent: 'center'}]}>
        <Text style={styles.statText}>x ducks</Text>
      </View>
    </ImageBackground>
    )
  }

  trex = () => {
    return(
      <ImageBackground
      source={require('../../assets/images/stats/bg-stats-weight-trex.jpg')}
      style={{ flex: 1, width: this.state.bgWidth, height: this.state.bgHeight, marginVertical: 25}}
      imageStyle={{ resizeMode: "contain" }}
    >
      <View style={{zIndex: 1, flexDirection: "row", justifyContent: 'center', marginTop: 5}}>
        <Text style={styles.statText}>
          <AnimateNumber
            value={this.state.stats.total_weight_carried}
            countBy={(this.state.stats.total_weight_carried / 50).toFixed(0)}
            style={styles.statTextData}
          />{" "}
          {i18n.t("stats.unit.kg")}
        </Text>
      </View>
      <View style={[styles.row, { marginTop: 450, alignItems: 'center', justifyContent: 'center'}]}>
        <Text style={styles.statText}>x ducks</Text>
      </View>
    </ImageBackground>
    )
  };

      choiceAction = (val) => {
        switch(val) {
          case "duck":
            this.duck();
          break;
          case "elephant":
            this.elephant();
          break;
          case "trex":
            this.trex();
          break;
          default:
            this.duck();
        }
      };
    
      render() {
        return (
          <ScrollView style={styles.containerScrollNoMargins}>
            <ImageBackground
              source={require("../../assets/images/background-stats.jpg")}
              style={{ flex: 1 }}
              imageStyle={{ resizeMode: "stretch" }}
            >
              <SafeAreaView>
                <View style={styles.rankingContainer}>
                  <Image
                    source={require("../../assets/images/cadran.png")}
                    style={styles.btnRanking}
                  />
                  <View style={[styles.row, { marginTop: 28, marginLeft: 55}]}>
                    <Text style={styles.statText}>{i18n.t("stats.action.weight")}</Text>
                  </View>
                  <Text
                    style={[styles.textimg, styles.measure]}
                    onLayout={this.handleLayout}
                  >
                    0
                  </Text>
                  <Image
                    source={require("../../assets/images/btn-header-background.png")}
                    style={styles.cadran}
                  />
                </View>
              </SafeAreaView>
              {this.choiceAction()}
              <View style={{flexDirection:'row', alignItems: 'center', justifyContent: 'space-around'}}>
                <TouchableOpacity
                  style={styles.zoom}
                  onPress={() => this.props.navigation.navigate("FlightsList")}
                >
                  <Image
                    source={require("../../assets/images/stats/btn-canard.png")}
                    style={styles.weightImg}
                  />
                </TouchableOpacity>
                <TouchableOpacity
                  style={styles.zoom}
                  onPress={this.choiceAction('duck')}
                >
                  <Image
                    source={require("../../assets/images/stats/btn-elephant.png")}
                    style={styles.weightImg}
                  />
                </TouchableOpacity>
                <TouchableOpacity
                  style={styles.zoom}
                  onPress={this.choiceAction('elephant')}
                >
                  <Image
                    source={require("../../assets/images/stats/btn-trex.png")}
                    style={styles.weightImg}
                  />
                </TouchableOpacity>
              </View>
              <View style={styles.subContainer}>
                <TouchableOpacity
                  style={styles.touchable2}
                  onPress={this.choiceAction('trex')}
                >
                  <View style={styles.view2}>
                    <Text style={styles.textimg2}>
                      {i18n.t("signup.action.back")}
                    </Text>
                  </View>
                  <Image
                    source={require("../../assets/images/btn-background.png")}
                    style={styles.tripsimg2}
                  />
                </TouchableOpacity>
              </View>
            </ImageBackground>
          </ScrollView>
        );
      }
    }

Solution

  • I have update the code. You were doing few things wrong.

    First

    onPress={this.choiceAction('duck')}
    

    onPress require a function but the way you do it will execute the function as soon the component render. A correct approach would be

    onPress={()=>this.choiceAction('duck')}
    

    Second

    choiceAction = (val) => {
            switch(val) {
              case "duck":
                this.duck();
              break;
              case "elephant":
                this.elephant();
              break;
              case "trex":
                this.trex();
              break;
              default:
                this.duck();
            }
          };
    

    This function wont return anything. It will surely execute other functions based on switch-case but it wont return anything.

    I have updated the code and make few adjustments to the function name. Take a look and let me know if this work at your end.

    export default class Weight extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                bgWidth: "100%",
                bgHeight: 0,
                animalBg: 'duck',
                stats: {
                    total_weight_carried: 0,
                },
                choice: ''
            };
        }
    
        setBackgroundDimensions = (real_width, real_height) => {
            let final_width = real_width;
            let final_height = real_height * (width * 100 / real_width) / 100;
    
            this.setState({
                bgWidth: "100%", // Force 100% for compatibility
                bgHeight: final_height
            });
    
            console.log(height, real_height, (width * 100 / real_width), final_height);
        };
    
        UNSAFE_componentWillMount() {
            // Image.getSize(bgStatsURL, (width, height) => {this.setBackgroundDimensions({width, height})});
            this.setBackgroundDimensions(1125, 1589);
        }
    
        duck = () => {
            return (
                <ImageBackground
                    source={require('../../assets/images/stats/bg-stats-weight-duck.jpg')}
                    style={{ flex: 1, width: this.state.bgWidth, height: this.state.bgHeight, marginVertical: 25 }}
                    imageStyle={{ resizeMode: "contain" }}
                >
                    <View style={{ zIndex: 1, flexDirection: "row", justifyContent: 'center', marginTop: 5 }}>
                        <Text style={styles.statText}>
                            <AnimateNumber
                                value={this.state.stats.total_weight_carried}
                                countBy={(this.state.stats.total_weight_carried / 50).toFixed(0)}
                                style={styles.statTextData}
                            />{" "}
                            {i18n.t("stats.unit.kg")}
                        </Text>
                    </View>
                    <View style={[styles.row, { marginTop: 450, alignItems: 'center', justifyContent: 'center' }]}>
                        <Text style={styles.statText}>x ducks</Text>
                    </View>
                </ImageBackground>
            )
        }
    
        elephant = () => {
            return (
                <ImageBackground
                    source={require('../../assets/images/stats/bg-stats-weight-elephant.jpg')}
                    style={{ flex: 1, width: this.state.bgWidth, height: this.state.bgHeight, marginVertical: 25 }}
                    imageStyle={{ resizeMode: "contain" }}
                >
                    <View style={{ zIndex: 1, flexDirection: "row", justifyContent: 'center', marginTop: 5 }}>
                        <Text style={styles.statText}>
                            <AnimateNumber
                                value={this.state.stats.total_weight_carried}
                                countBy={(this.state.stats.total_weight_carried / 50).toFixed(0)}
                                style={styles.statTextData}
                            />{" "}
                            {i18n.t("stats.unit.kg")}
                        </Text>
                    </View>
                    <View style={[styles.row, { marginTop: 450, alignItems: 'center', justifyContent: 'center' }]}>
                        <Text style={styles.statText}>x ducks</Text>
                    </View>
                </ImageBackground>
            )
        }
    
        trex = () => {
            return (
                <ImageBackground
                    source={require('../../assets/images/stats/bg-stats-weight-trex.jpg')}
                    style={{ flex: 1, width: this.state.bgWidth, height: this.state.bgHeight, marginVertical: 25 }}
                    imageStyle={{ resizeMode: "contain" }}
                >
                    <View style={{ zIndex: 1, flexDirection: "row", justifyContent: 'center', marginTop: 5 }}>
                        <Text style={styles.statText}>
                            <AnimateNumber
                                value={this.state.stats.total_weight_carried}
                                countBy={(this.state.stats.total_weight_carried / 50).toFixed(0)}
                                style={styles.statTextData}
                            />{" "}
                            {i18n.t("stats.unit.kg")}
                        </Text>
                    </View>
                    <View style={[styles.row, { marginTop: 450, alignItems: 'center', justifyContent: 'center' }]}>
                        <Text style={styles.statText}>x ducks</Text>
                    </View>
                </ImageBackground>
            )
        };
        setChoiceAction = (choice) => this.setState({ choice })
        getChoiceAction = () => {
            switch (this.state.choice) {
                case "duck":
                    return this.duck();
                case "elephant":
                    return this.elephant();
                case "trex":
                    return this.trex();
                default:
                    this.duck();
            }
        };
    
        render() {
            return (
                <ScrollView style={styles.containerScrollNoMargins}>
                    <ImageBackground
                        source={require("../../assets/images/background-stats.jpg")}
                        style={{ flex: 1 }}
                        imageStyle={{ resizeMode: "stretch" }}
                    >
                        <SafeAreaView>
                            <View style={styles.rankingContainer}>
                                <Image
                                    source={require("../../assets/images/cadran.png")}
                                    style={styles.btnRanking}
                                />
                                <View style={[styles.row, { marginTop: 28, marginLeft: 55 }]}>
                                    <Text style={styles.statText}>{i18n.t("stats.action.weight")}</Text>
                                </View>
                                <Text
                                    style={[styles.textimg, styles.measure]}
                                    onLayout={this.handleLayout}
                                >
                                    0
                      </Text>
                                <Image
                                    source={require("../../assets/images/btn-header-background.png")}
                                    style={styles.cadran}
                                />
                            </View>
                        </SafeAreaView>
                        {this.getChoiceAction()}
                        <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-around' }}>
                            <TouchableOpacity
                                style={styles.zoom}
                                onPress={() => this.props.navigation.navigate("FlightsList")}
                            >
                                <Image
                                    source={require("../../assets/images/stats/btn-canard.png")}
                                    style={styles.weightImg}
                                />
                            </TouchableOpacity>
                            <TouchableOpacity
                                style={styles.zoom}
                                onPress={() => this.setChoiceAction('duck')}
                            >
                                <Image
                                    source={require("../../assets/images/stats/btn-elephant.png")}
                                    style={styles.weightImg}
                                />
                            </TouchableOpacity>
                            <TouchableOpacity
                                style={styles.zoom}
                                onPress={() => this.setChoiceAction('elephant')}
                            >
                                <Image
                                    source={require("../../assets/images/stats/btn-trex.png")}
                                    style={styles.weightImg}
                                />
                            </TouchableOpacity>
                        </View>
                        <View style={styles.subContainer}>
                            <TouchableOpacity
                                style={styles.touchable2}
                                onPress={() => this.setChoiceAction('trex')}
                            >
                                <View style={styles.view2}>
                                    <Text style={styles.textimg2}>
                                        {i18n.t("signup.action.back")}
                                    </Text>
                                </View>
                                <Image
                                    source={require("../../assets/images/btn-background.png")}
                                    style={styles.tripsimg2}
                                />
                            </TouchableOpacity>
                        </View>
                    </ImageBackground>
                </ScrollView>
            );
        }
    }