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

注意:当前测试的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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值