如何在按钮按下时将按钮的当前图像更改为另一个图像

时间:2017-08-04 08:08:48

标签: javascript reactjs react-native

在我的应用程序的主屏幕中,我有两个按钮,如果用户选择一个按钮,通过将其当前图像更改为另一个按钮来显示触摸的响应我尝试了所有设置状态和传递条件的方法,但它&# 39;不工作

这是我的代码MainScreen.js文件:



import React, { Component } from 'react';
import { StatusBar, Image, TouchableHighlight } from 'react-native';
import { Actions } from 'react-native-router-flux';

class MainScreen extends Component {
  state = {
    computerPressed: false,
    teamPressed: true
  }
  render() {
return (
  <Image
  source={require('./Images/bg_img.png')}
  style={styles.backgroundStyle} >

  <StatusBar hidden />

    <Image
    source={require('./Images/History.png')}
    style={styles.historybuttonStyle} />

    <Image
    source={require('./Images/logo_ws.png')}
    style={styles.logoStyle} />

<TouchableHighlight onPress={() => Actions.screen2({ challenge: 'Computer' })}
onPressIn={this.state.computerPressed = true}
onPressOut={this.state.computerPressed}>
    <Image
    source={require(this.state.computerPressed ? './Images/landing-bnt1-on.png' : './Images/landing-bnt1.png')}
    style={styles.landingbnt1Style} />
</TouchableHighlight>

<TouchableHighlight onPress={() => Actions.screen2({ challenge: 'Team' })}
onPressIn={this.state.teamPressed = true}
onPressOut={this.state.teamPressed}>
    <Image
    source={require(this.state.computerPressed ? './Images/landing-bnt2-on.png' : './Images/landing-bnt2.png')}
    style={styles.landingbnt2Style} />
</TouchableHighlight>

</Image>
);
}
}
const styles = {

 backgroundStyle: {
    flex: 1,
    width: undefined,
    height: undefined,
    justifyContent: 'center',
    alignItems: 'center',
    flexWrap: 'wrap',
    position: 'relative'
  },
  logoStyle: {
    flex: 0,
    width: 340,
    height: 270,
    resizeMode: 'contain',
    marginBottom: 150,
    position: 'absolute',
    bottom: 50
  },
  historybuttonStyle: {
    width: 38,
    height: 35,
    position: 'absolute',
    right: 5,
    top: 10
  },
  landingbnt1Style: {
    width: 250,
    height: 45,
    top: 175
  },
  landingbnt2Style: {
    width: 250,
    height: 45,
    top: 200
  }
};
export default MainScreen;
&#13;
&#13;
&#13;

我执行此代码时弹出此错误:

1st error

当我将代码更改为:

&#13;
&#13;
import React, { Component } from 'react';
import { StatusBar, Image, TouchableHighlight } from 'react-native';
import { Actions } from 'react-native-router-flux';

const a = require('./Images/landing-bnt1-on.png');
const b = require('./Images/landing-bnt1.png');
const c = require('./Images/landing-bnt2-on.png');
const d = require('./Images/landing-bnt2.png');

class MainScreen extends Component {
  state = {
    computerPressed: false,
    teamPressed: true
  }
  render() {
return (
  <Image
  source={require('./Images/bg_img.png')}
  style={styles.backgroundStyle} >

  <StatusBar hidden />

    <Image
    source={require('./Images/History.png')}
    style={styles.historybuttonStyle} />

    <Image
    source={require('./Images/logo_ws.png')}
    style={styles.logoStyle} />

<TouchableHighlight
onPress={() => Actions.screen2({ challenge: 'Computer' })}
onPressIn={this.state.computerPressed = true}
onPressOut={this.state.computerPressed}>
    <Image
    source={require(this.state.computerPressed ? a : b)}
    style={styles.landingbnt1Style} />
</TouchableHighlight>

<TouchableHighlight
onPress={() => Actions.screen2({ challenge: 'Team' })}
onPressIn={this.state.teamPressed = true}
onPressOut={this.state.teamPressed}>
    <Image
    source={require(this.state.computerPressed ? c : d)}
    style={styles.landingbnt2Style} />
</TouchableHighlight>

</Image>
);
}
}
const styles = {

 backgroundStyle: {
    flex: 1,
    width: undefined,
    height: undefined,
    justifyContent: 'center',
    alignItems: 'center',
    flexWrap: 'wrap',
    position: 'relative'
  },
  logoStyle: {
    flex: 0,
    width: 340,
    height: 270,
    resizeMode: 'contain',
    marginBottom: 150,
    position: 'absolute',
    bottom: 50
  },
  historybuttonStyle: {
    width: 38,
    height: 35,
    position: 'absolute',
    right: 5,
    top: 10
  },
  landingbnt1Style: {
    width: 250,
    height: 45,
    top: 175
  },
  landingbnt2Style: {
    width: 250,
    height: 45,
    top: 200
  }
};
export default MainScreen;
&#13;
&#13;
&#13;

弹出错误:

2nd-error

那我怎么能得到这个功能呢?

4 个答案:

答案 0 :(得分:2)

有一些规则你必须遵循react-native:

图片不能有条件require

<Image
    source={require(this.state.computerPressed ? './Images/landing-bnt1-on.png' : './Images/landing-bnt1.png')}
    style={styles.landingbnt1Style} />

此声明无效。这就是您收到第一条错误消息的原因Unknown named module: '../images/landing-btn1-on.png'

而是静态加载图片:

const image_btn1 = require('./Images/landing-btn1.png');
const image_btn1_on = require('./Images/landing-btn1-on.png');

并有条件地在它们之间切换。

<Image
    source={this.state.computerPressed ? image_btn1_on : image_btn1}
    style={styles.landingbnt1Style} />

JSX函数应该有效:

JSX功能无法使用此模式。

onPressIn={this.state.computerPressed = true}
onPressOut={this.state.computerPressed}>

改为:

onPressIn={() => { this.state.computerPressed = true }}
onPressOut={ () => { this.state.computerPressed = false }}>

您应始终在构造函数之外使用setState()

render()不会被触发。

所以先前的表达式变为:

onPressIn={() => {
    this.setState({computerPressed: true });
}
onPressOut={ () => {
    this.setState({computerPressed: false });
}

答案 1 :(得分:0)

您的node_modules看起来有问题或冲突。

尝试删除node_modules文件夹,然后在终端中运行

nom install

答案 2 :(得分:0)

I have solved this problem hope it helps for others

I have changed from TouchableHighlight to TouchableWithoutFeedback

and made few changes as suggested as answers thank you @Val

So here's my code:

import React, { Component } from 'react';
import { StatusBar, Image, TouchableWithoutFeedback } from 'react-native';
import { Actions } from 'react-native-router-flux';

const a = require('./Images/landing-bnt1-on.png');
const b = require('./Images/landing-bnt1.png');
const c = require('./Images/landing-bnt2-on.png');
const d = require('./Images/landing-bnt2.png');

class MainScreen extends Component {
  state = {
    computerPressed: false,
    teamPressed: false
  }
  render() {
return (
  <Image
  source={require('./Images/bg_img.png')}
  style={styles.backgroundStyle} >

  <StatusBar hidden />

    <Image
    source={require('./Images/History.png')}
    style={styles.historybuttonStyle} />

    <Image
    source={require('./Images/logo_ws.png')}
    style={styles.logoStyle} />

<TouchableWithoutFeedback
onPress={() => {
  Actions.screen2({ challenge: 'Computer' });
  }
}
onPressIn={() => {
    this.setState({ computerPressed: true });
  }
}
onPressOut={() => {
    this.setState({ computerPressed: false });
}
} >
    <Image
    source={this.state.computerPressed ? a : b}
    style={styles.landingbnt1Style} />
</TouchableWithoutFeedback>

<TouchableWithoutFeedback
onPress={() => {
  Actions.screen2({ challenge: 'Team' });
  }
}
onPressIn={() => {
    this.setState({ teamPressed: true });
  }
}
onPressOut={() => {
    this.setState({ teamPressed: false });
}
} >
    <Image
    source={this.state.teamPressed ? c : d}
    style={styles.landingbnt2Style} />
</TouchableWithoutFeedback>

</Image>
);
}
}
const styles = {

 backgroundStyle: {
    flex: 1,
    width: undefined,
    height: undefined,
    justifyContent: 'center',
    alignItems: 'center',
    flexWrap: 'wrap',
    position: 'relative'
  },
  logoStyle: {
    flex: 0,
    width: 340,
    height: 270,
    resizeMode: 'contain',
    marginBottom: 150,
    position: 'absolute',
    bottom: 50
  },
  historybuttonStyle: {
    width: 38,
    height: 35,
    position: 'absolute',
    right: 5,
    top: 10
  },
  landingbnt1Style: {
    width: 250,
    height: 45,
    top: 175
  },
  landingbnt2Style: {
    width: 250,
    height: 45,
    top: 200
  }
};
export default MainScreen;

答案 3 :(得分:0)

在0.63版中,React Native引入了一个新的核心组件Pressable来解决此问题:

   import { Pressable, Text, View } from 'react-native';

    <Pressable onPress={() => { alert("doSomething") }}>
      {({ pressed }) => (
        <View style={{ flexDirection: 'row' }}>
          <Text> Toggle Image </Text>
          {pressed 
            ? <Image source={ require('../assets/img-pressed.png') } /> 
            : <Image source={ require('../assets/img.png') } />}
        </View>
      )}
    </Pressable>

您还可以通过执行以下操作来调整wrapper元素的样式:

    <Pressable onPress={() => { alert("doSomething") }} 
      style={({ pressed }) => [
      {
        backgroundColor : pressed
          ? 'red'
          : 'green'
      }
      ]}>
      {({ pressed }) => (
        <View style={styles.myCustomStyleWithoutBackgroundColor}>
          <Text> Toogle Image and Background Color </Text>
          {pressed 
            ? <Image source={ require('../assets/img-pressed.png') } /> 
            : <Image source={ require('../assets/img.png') } />}
        </View>
      )}
    </Pressable>