在ListView中更改选择器React Native

时间:2016-09-06 11:38:05

标签: react-native

我希望你能帮助我。我有一个来自api的自行车的列表视图。我每行都有一个拣货员来租一些自行车。选择器的selectedValue在每一行中都是相同的。因此,当我在一行中更改选择器时,每行中的数字都会发生变化,因为我使用setState来更改它。我不想更改dataSource,只想更改一行的状态。我已经搜索过,但我找不到合适的答案。

这是我的代码:

 import React, { Component } from 'react';
 import {
  Text,
  View,
  StyleSheet,
  ListView,
  Image,
  TouchableHighlight,
  TextInput,
  Picker,
  Item,
  Alert,
  ScrollView
 } from 'react-native';

 import MapView from 'react-native-maps';
 import DatePicker from 'react-native-datepicker';

 import FourthScreen from './FourthScreen';

 export default class ThirdScreen extends Component {

 constructor(props) {
  super(props);

  this.state = {
   dataSource: new ListView.DataSource({
     rowHasChanged: (row1, row2) => row1 !== row2,
   }),
   bikes: [],
   bikeCount: 0,
   region: {
    latitude: this.props.latitude,
    longitude: this.props.longitude,
    latitudeDelta: 0.06,
    longitudeDelta: 0.06
   },
   count: '0',
   price: 0.00,
   date1: '',
   date2: '',
   amount: '0',
   numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
   totalPrice: 0.00
 }
}

componentWillMount() {
 this.getBikesFromApiAsync();
}

getBikesFromApiAsync() {
 return fetch(`https://api.bimbimbikes.com/locations/${this.props.id}/bikes`,                 {
  method: 'GET',
  headers: {
    'Authorization': 'Basic ',
  }
})
.then((response) => response.json())
.then((json) => {
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(json.data.results),
    bikes: json.data.results
  });
  console.log(this.state.dataSource);
  console.log(this.state.bikes);
})
.catch((error) => {
  console.error(error);
})
.done();
}

render() {
var bikeCount = this.state.bikes.length;
return (
  <ScrollView>
    <View style={styles.container}>
      <View style={styles.viewMapView}>
        <MapView
          style={styles.mapView}
          region={this.state.region}>
          <MapView.Marker
            coordinate={this.state.region}
            title={this.props.name}
          />
        </MapView>
      </View>
      <Text style={styles.textStyle}>{this.props.name}</Text>
      <Text style={styles.textStyle}>{this.props.city_name}, {this.props.country_name}</Text>
      <View style={styles.date}>
        <DatePicker
          style={{width: 300, marginBottom: 10}}
          date={this.state.date1}
          mode="date"
          placeholder="Startdatum"
          format="DD-MM-YYYY"
          confirmBtnText="Confirm"
          cancelBtnText="Cancel"
          onDateChange={(date1) => {this.setState({date1: date1});}}/>
        <DatePicker
          style={{width: 300}}
          date={this.state.date2}
          mode="date"
          placeholder="Einddatum"
          format="DD-MM-YYYY"
          confirmBtnText="Confirm"
          cancelBtnText="Cancel"
          onDateChange={(date2) => {this.setState({date2: date2});}}/>
      </View>
      <Text style={styles.textStyle}>{bikeCount.toString()} Fietsen</Text>
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderBikesRow.bind(this)}
      />
    <Text style={styles.textStyle}>Prijs: € {this.state.price}</Text>
      <View style={styles.buttonView}>
        <TouchableHighlight style={styles.button} onPress={() => this.reserveBike()}>
          <Text style={styles.buttonText}>Reserveer Nu</Text>
        </TouchableHighlight>
      </View>
    </View>
  </ScrollView>
)
}

reserveBike() {
 if(this.state.date1 && this.state.date2) {
  this.props.navigator.push({
    component: FourthScreen,
    passProps: {
      date1: this.state.date1,
      date2: this.state.date2,
      name: this.props.name,
      city_name: this.props.city_name,
      country_name: this.props.country_name,
      total: this.state.total
    }
  });
} else {
  Alert.alert(
    'Choose Date',
    'You have to choose a date'
  );
}
}

onValueChange(key: number, value: number) {
 console.log(key);
 console.log(value);
}

renderBikesRow(rowData, sectionId, rowId, highlightrow) {
 console.log(rowData, sectionId, rowId, highlightrow);
 var price = rowData.prices['24h'] / 100;
 var amount = this.state.amount;
 return (
  <View style={styles.row}>
    <Text style={styles.textStyleBike}>{rowId}: {rowData.name}</Text>
    <Picker
      style={styles.picker}
      selectedValue={this.state.amount}
      onValueChange={(number) => this.setState({amount: number, price: number * price})}
      mode="dropdown">
      {this.state.numbers.map((number) => {return <Picker.Item value={number} label={number.toString()} key={number}/> })}
    </Picker>
    <Text style={styles.textStylePrice}>€ {price}</Text>
  </View>
)
}
}

var styles = StyleSheet.create({
 container: {
  flex: 1,
  marginTop: 60,
  backgroundColor: 'rgb(82, 71, 72)'
 },
 viewMapView: {
  alignItems: 'center'
 },
 mapView: {
  width: 300,
  height: 200,
  marginTop: 10,
  alignItems: 'center'
 },
  textStyle: {
  margin: 10,
  color: '#fff',
  fontSize: 20,
  textAlign: 'center'
 },
 date: {
  alignItems: 'center',
 },
 row: {
  flex: 5,
  flexDirection: 'row',
  borderBottomWidth: 1
 },
 textStyleBike: {
  color: '#ffa405',
  fontSize: 20,
  paddingTop: 15,
  paddingRight: 10,
  paddingLeft: 10,
  flex: 3
 },
 textInput: {
  height: 50,
  width: 50,
  textAlign: 'center',
  flex: 1,
  fontSize: 20
 },
 picker: {
  flex: 1,
  height: 50
 },
 textStylePrice: {
  color: '#ffa405',
  fontSize: 20,
  paddingTop: 15,
  paddingRight: 10,
  paddingLeft: 10,
  flex: 1
 },
 button: {
  height: 40,
  width: 300,
  justifyContent: 'center',
  alignItems: 'center',
  backgroundColor: '#ffa405',
  marginBottom: 10
},
buttonText: {
 fontSize: 18,
 fontWeight: '600'
},
buttonView: {
 alignItems: 'center'
}
});

2 个答案:

答案 0 :(得分:0)

将金额作为对象。

this.setState({
    amount: {}
  });

将选择器附加到适当的数量。

<Picker
      style={styles.picker}
      selectedValue={this.state.amount[rowId]}
      onValueChange={(number) => this.setState({amount[rowId]: number, price: number * price})}
      mode="dropdown">
      {this.state.numbers.map((number) => {return <Picker.Item value={number} label={number.toString()} key={number}/> })}
    </Picker>

答案 1 :(得分:0)

我找到了解决方案。我将Picker更改为TextInput,但原理相同。

您必须创建一个新数组并将该数量放在具有相同rowId的对象中。

onChangeTextRow(rowId: string, count: number, price: number) {
 var newArray = [];
 newArray = this.state.bikes.concat();
 newArray[rowId] = {
  ...this.state.bikes[rowId],
  amount: count
 }
 this.setState({
  dataSource: this.state.dataSource.cloneWithRows(newArray),
  bikes: newArray,
  totalPrice: this.state.totalPrice + count * price
 });
 console.log(newArray);
}

renderBikesRow(rowData, sectionId, rowId, highlightrow) {
 var price = rowData.prices['24h'] / 100;
 return (
  <View style={styles.row}>
    <Text style={styles.textStyleBike}>{rowId}: {rowData.name}</Text>
      <TextInput
        style={styles.textInput}
        placeholder="0"
        value={rowData.amount}
        onChangeText={(count) => this.onChangeTextRow(rowId, count, price)}
        underlineColorAndroid="transparent"
        keyboardType="numeric"
        />
    <Text style={styles.textStylePrice}>€ {price}</Text>
  </View>
 )
}