如何在Listview组件中使用条件?

时间:2019-03-29 23:16:57

标签: react-native

我需要使用条件作为更改背景TouchableOpacity。在Listview以外的条件下可以正常工作,但在ListView下则不能正常工作。

如何在Listview使用条件

      constructor(props){
        super(props);
        this.state={
          deliver:'',
        }
      }

      render() {
        return(
          <ListView
            dataSource={this.state.dataSource}
            renderRow={ (rowData)=>
              <TouchableOpacity 
                onPress={()=>this.setState({deliver:rowData})} 
                activeOpacity={0.5} 
                style={[styles.row, { backgroundColor: this.state.deliver === rowData ? '#0077FF' : '#eee'}]}>
                <Text>{rowData}</Text>
              </TouchableOpacity>
            }/>
         );
      }

      const styles = StyleSheet.create({
         row:{
           borderRadius:5,
           marginTop:5,
           paddingTop:5,
           paddingBottom:5
         },
      });

2 个答案:

答案 0 :(得分:2)

更新后的答案: 由于ListView的行仅在ListViewDataSource被更改时才自行重新呈现,因此在这种情况下backgroundColor不会更新。

顺便说一句,ListView实际上已被弃用。 React Native建议使用其FlatListSectionListRead this for more info

更新这些行的最简单方法可能就是将这些行分解成自己的组件。

您的ListView组件如下所示:

      <ListView
        style={styles.container}
        dataSource={this.state.dataSource}
        renderRow={rowData => <Row data={rowData} />}
      />

您的Row组件看起来像这样:

class Row extends React.Component {
  constructor(props) {
    super(props);

    this.state = { selected: false };
  }

  toggleSelected = () => {
    this.setState({ selected: !this.state.selected });
  };

  render() {
    return (
      <TouchableOpacity
        style={{
          backgroundColor: this.state.selected ? 'red' : 'yellow',
        }}
        onPress={this.toggleSelected}>
        <Text>{this.props.data}</Text>
      </TouchableOpacity>
    );
  }
}

这里有snack展示了它的作用! :)

原始答案:

看起来应该在使用大括号[]的情况下使用方括号{}

有两种解决方法。

  1. 有2种样式可供您选择。这是您要尝试的操作,但是添加[]会使您绊倒。 []括号仅在您要输入样式的 array 时使用。因此,在您的情况下,这应该起作用:
<TouchableOpacity
  style={ this.state.selected ? styles.selected : styles.unselected }
  onPress={...}
/>
  1. 具有一种共享样式,仅更改backgroundColor。此方法比较干净,因为样式中的代码重复较少。在这里使用[]括号是因为我们要提供样式数组。根据RN的style docs,数组每个索引中的样式元素将覆盖前一个索引中的样式元素。因此,仅更改backgroundColor,这就是您可以做到的方式。
<TouchableOpacity
  style={[styles.row, { backgroundColor: this.state.selected ? 'blue' : 'eee'}]}
  onPress={...}
/>

const styles = StyleSheet.create({
  row: {
    backgroundColor:'white',
    borderRadius:5,
    marginTop:5
  },
});

答案 1 :(得分:1)

我添加了一些示例代码,说明如何在listview行单击中实现条件样式。我根据您的要求编写基本代码,您可以对其进行自定义。请检查以下代码,我还添加了快餐.expo.io,以便您可以直接运行到设备中。

https://snack.expo.io/@vishal7008/listview

从'react'导入*作为React; 从'expo'导入{常量};

// You can import from local files
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
  TouchableHighlight
} from 'react-native';

export default class App extends React.Component {

   constructor(props) {
    super(props);

    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      data: this._genRow(),
      dataSource: ds.cloneWithRows(this._genRow()),
    }
  }

  _genRow(){
    var datas = [];
    for (var i = 0; i < 5; i++) {
      datas.push({
        row: i,
        isSelect: false,
      });
    }
    console.log('datas ' + JSON.stringify(datas));
    return datas;
  }

componentDidMount() {
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(this.state.data)
    });
  }

  render() {
    return (
      <ListView
        dataSource = {this.state.dataSource}
        renderRow = {this._renderRow.bind(this)}
        renderHeader = {() => <View style={{height: 10, backgroundColor: '#f5f5f5'}} />}
        onEndReached = {() => console.log('')}
        renderSeparator = {(sectionID, rowID) =>
          <View
            style={styles.style_separator}
            key={`${sectionID} - ${rowID}`}
          />}
      />
    );
  }

  _renderRow(rowData: string, sectionID: number, rowID: number) {
    console.log('render row ...');
    return (
      <TouchableHighlight onPress={this._onPressRow.bind(this, rowID, rowData)}>{rowData.isSelect ?
        <View style={styles.style_row_view}>
          <Text style={styles.style_text}>{rowData.row}</Text>
          <Text style={styles.style_text}>{rowData.isSelect ? 'true' : 'false'}</Text>
        </View>

        :
        <View style={styles.style_row_view1}>
          <Text style={styles.style_text}>{rowData.row}</Text>
          <Text style={styles.style_text}>{rowData.isSelect ? 'true' : 'false'}</Text>
        </View>
        }
      </TouchableHighlight>
    );
  }

  _onPressRow(rowID, rowData) {
  rowData.isSelect = !rowData.isSelect;
    var dataClone = this.state.data;
    dataClone[rowID] = rowData;
    this.setState({
      data: dataClone
    });
    console.log(this.state.data);
  }
}


const styles = StyleSheet.create({
  style_row_view: {
    flex: 1,
    flexDirection: 'row',
    height: 57,
    backgroundColor: '#FF0',
  },style_row_view1: {
    flex: 1,
    flexDirection: 'row',
    height: 57,
    backgroundColor: '#0FF',
  },
  style_text: {
    flex: 1,
    marginLeft: 12,
    fontSize: 16,
    color: '#333333',
    alignSelf: 'center',
  },

});