React Native实现双列简单瀑布流布局

2,759 阅读1分钟

实现原理:

分为两列布局,外套滚动组件 <ScrollView> ,一开始左瀑布先加载第一条数据,右瀑布加载第二条数据,然后开始分别记录左右瀑布的高度,接着判断左右瀑布的高度,高度小者优先拼接第三条数据,以此类推。。。

瀑布流代码

/**
 *  瀑布流Demo
 */
 import React , {PureComponent} from 'react'
 import {
     StyleSheet,
     View,
     Text,
     Image,
     InteractionManager,
     ScrollView,
 } from 'react-native'
 
 import NavigatorBarView from '../Components/NavigationBar/NavigatorBarView'
 import {getExploitEstateListAction} from "../module/Nailing/NailingAction";
 
 const width = (Common.size.width-20)/2;
 
 
 export default class CertificateAuthority extends PureComponent{
     constructor(props) {
         super(props);
         this.state = {
             params: {
                 page: 1,
                 pageSize: 50,
             },
             data: []
         }
     }
 
     componentDidMount() {
         InteractionManager.runAfterInteractions(()=> {
             ShowLoading();
             getExploitEstateListAction(this.state.params, (result, status)=> {
                 console.log('result :', result);
                 if(status) {
                     let tag = 0
                     for(let i = 0; i < result.data.length; i++) {
                         const eleData = result.data[i];
                         //获取网络图片的尺寸信息
                         Image.getSize(
                             eleData.coverImg||'',
                             (w, h) => {
                                 let proportion = w/width;//计算网络图片的原始宽高比
                                 let height = h/proportion;//计算新高度
                                 eleData['height'] = height;//为数据添加高度字段,便于渲染
                                 eleData['tag'] = i;
                                 //格式化完最后一条数据才更新总数据
                                 if(tag == result.data.length-1) {
                                     this.setState({data: result.data})//更新图片总数据
                                 }
                                 console.log(i, '---', eleData.houseName)
                                 tag++;
                             },
                             (error => {
                                 eleData['height'] = width;
                                 eleData['tag'] = i;
                                 if(tag == result.data.length-1) {
                                     this.setState({data: result.data})
                                 }
                                 console.log(i, '---', eleData.houseName)
                                 tag++;
                             })
                         );
                     }
                 }else {
                     this.setState({data: []})
                 }
                 HideLoading();
             })
         })
     }
 
     renderItem = (eleData)=> {
         return (
             <View style = {{margin: 5,}}>
                 <Image style = {{width: width, height: eleData.height, borderTopLeftRadius: 10,
                     borderTopRightRadius: 10}}
                        source = {{uri: eleData.coverImg}}/>
                 <View style = {[styles.itemText, {height: eleData.houseName.length >=10?60: 40}]}>
                     <Text>{"编号:"+eleData.tag}</Text>
                     <Text style={{width: width-20, textAlign: 'center'}}>{eleData.houseName}</Text>
                 </View>
             </View>
         )
     }
 
     render() {
         let content_a = [], content_b = [], height_a = 0, height_b = 0;
 
         for(let i = 0; i < this.state.data.length; i++) {
             const eleData = this.state.data[i];
             let textHeight = eleData.houseName.length >= 10?60: 40
             if(i == 0) {
                 height_a += eleData.height+textHeight+10;
                 content_a.push(this.renderItem(eleData));
             }else if(i == 1) {
                 height_b += eleData.height+textHeight+10;
                 content_b.push(this.renderItem(eleData));
             }else {
                 if(height_a < height_b) {
                     height_a += eleData.height+textHeight+10;
                     content_a.push(this.renderItem(eleData));
                 }else {
                     height_b += eleData.height+textHeight+10;
                     content_b.push(this.renderItem(eleData));
                 }
             }
         }
 
         return(
             <View style={{flex:1,backgroundColor:'#f7f7f7'}}>
                 <NavigatorBarView title = {'页面标题'}/>
                 <ScrollView>
                     <View style = {{width: Common.size.width, flexDirection: 'row'}}>
                         <View>
                             {content_a}
                         </View>
 
                         <View>
                             {content_b}
                         </View>
                     </View>
                 </ScrollView>
             </View>
         )
     }
 }
 const styles = StyleSheet.create({
     itemText: {
         justifyContent: 'space-between',
         alignItems: 'center',
         paddingHorizontal: 10,
         backgroundColor: '#0002',
         borderBottomLeftRadius: 10,
         borderBottomRightRadius: 10
     },
 })