react-Native ListView中实现单击行展开效果

来源:互联网 发布:列式数据库 olap 编辑:程序博客网 时间:2024/05/19 19:59

注意:当前测试的react-native版本为 0.36.0,上次碰到版本忘记的好像是0.30.0这个动画无效果,高度收不起来,具体原因未知,但是较早的版本好像又有用的,所以刚好有些朋友碰到的版本无效的可能要换种思维去处理了,避免把你带入坑而死磕,特此注明。

大致思路挺简单的:

  1、展开效果可以通过Animated动画来实现,思路大致为,给Animated高度为0,当单击时Animated展开一定高度,这样就完成了展开的效果

  2、ListView是以单个显示元素来累积起来的,所以可以写一个组件,主要包含listView中显示部分和隐藏部分(即需要单击展开收起部分)。


测试代码如下:

  自定义listView单个元素组件,包含可视部分和隐藏展开收起部分,自定义元素代码如下,文件名称为ListCards.js

import React, { Component } from 'react';import {  StyleSheet,  Text,  View,  TouchableOpacity,  Animated} from 'react-native';class ListCards extends Component {  constructor(props) {    super(props);    this.state={       ...props,       showAnim:new Animated.Value(0)     };     this.showorhide=0;  }  _showorhideItems(){    if(typeof(this.state.name)=='undefined'||this.state.name==null){      return;    }    Animated.timing(          // Uses easing functions       this.state.showAnim,    // The value to drive       {         toValue: this.showorhide==0?1:0       }            // Configuration     ).start();     this.showorhide=this.showorhide==0?1:0;  }  render(){    return(      <View>        <TouchableOpacity onPress={this._showorhideItems.bind(this)}>        <View style={styles.headerLine}>         <View style={styles.headerRows}><Text>{this.state.name}</Text></View>        </View>        </TouchableOpacity>        <Animated.View         style={{           height:this.state.showAnim.interpolate({             inputRange: [0, 1],             outputRange: [0, 110]           }),           overflow:'hidden'         }        }        >        <View style={styles.showitemContain}>         <View style={{height:50}}>           <Text>{this.state.title==null?'':this.state.title}</Text>         </View>         <View style={{height:60}}>           <Text>{this.state.fromwhere==null?'':this.state.fromwhere}</Text>         </View>         </View>        </Animated.View>      </View>    )  }}const styles=StyleSheet.create({  headerLine:{    height:50,    flexDirection:'row',    borderBottomWidth:1,    borderBottomColor:'red',  },  headerRows:{    flex:1,    justifyContent:'center',    alignItems:'center',  },  showitemContain:{    borderWidth:1,    borderColor:'red',    height:110,    justifyContent:'center',    alignItems:'center',  }});module.exports=ListCards;


listView测试代码,名称为ListContent.js:

import React, { Component } from 'react';import {  StyleSheet,  Text,  View,  ListView} from 'react-native';import ListCards from './listcards';class ListContent extends Component{  constructor(props) {    super(props);    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});    this.state={      dataSource: ds.cloneWithRows(this._genrows()),    };  }  // componentWillMount(){  //   this.setState({dataSource:this.state.dataSource.cloneWithRows(this._genrows())});  // }  _genrows(){    var rows=[];    for(let i=0;i<5;i++){      var rowtmp={};      rowtmp.name='测试'+i;      rowtmp.title='标题'+i;      rowtmp.fromwhere='来源'+i;      rows.push(rowtmp);    }    console.log(JSON.stringify(rows));    return rows;  } _renderRows(rowData){   return(     <ListCards name={rowData.name} title={rowData.title} fromwhere={rowData.fromwhere} />   ) }  render(){    return(      <ListView        dataSource={this.state.dataSource}        renderRow={(rowData) =>this._renderRows(rowData)}      />    )  }}module.exports=ListContent;


测试,我在android.index.js中测试:

import React, { Component } from 'react';import {  AppRegistry,  StyleSheet,  Text,  View} from 'react-native';import ListContent from './component/listContent';AppRegistry.registerComponent('testProject', () => ListContent);

效果为:单击某一行,则展开那一行的隐藏数据,太晚了,就懒得做gif图看效果了,直接复制粘贴,运行测试一下便可以看到效果了,根据这样的思路,便可以完成自己想要的展开的内容了,good luck。



 

0 0
原创粉丝点击