Flutter开发--------动态表格

前言

工作中,都会有这样子的需求,就是一张表格的行列都是动态生产的。博主最近也遇到了这个需求,一直研究了一个星期,总算写出来了。现在在这里和大家分享一下。

准备工具

这套课程是采用VScode进行开发的。当前在此之前请准备好Flutter开发环境,我这里就不进行讲解了。

实现界面

下面表格中的行列都是动态生产的

在这里插入图片描述

实例代码分析

这里实例的特点是: UI和数据进行分离,使用到了状态管理。

数据处理

创建一个table.dart中有一个TableProvide类,对从后端提到的数据进行处理

import 'package:flutter/material.dart';
import '../service/service_method.dart';

class TableProvide with ChangeNotifier{ 
  List<String> keyList=[];				//后端json中的key值
  List contextList=[];					//后端json内容
  List titleList=[];					//后端数据中的标题信息
  List contextNum=[];					//统计有几行数据
  List openState=[];  					//判断+号的状态
  int count;
  dynamic openNum;

  getTableInfo() async{
    await request('getCommodity').then((val){
      contextList=val;
      keyList=['number','price'];
      titleList=['操作','数量','价格'];
      count=contextList.length;     
      for(int i=0;i<count;i++){
        contextNum.add(i);
        openState.add({'symbol':'+'});
      }
    });
  }
 //编写一个改变符号函数,一开始是+号,之后点击之后,对应的 + 号会变成 - 号; - 号会编程 + 号
  changeOpenState(){				
    for(int i=0;i<count;i++){
        openState[i]['symbol']='+';
      }
    openState[openNum]['symbol']='-';
    notifyListeners();
  }
}

表格处理

我们这里使用DataTable这个组件

行列处理

		DataTable(
			// 标题区域
          columns: Provide.value<TableProvide>(context).titleList.map((data)=>DataColumn(
            label: Text(data)
          )).toList(),
          //内容区域  
          rows: Provide.value<TableProvide>(context).contextNum.map((data)=>
                  DataRow(
                    cells:  _getCells(Provide.value<TableProvide>(context).keyList,data,Provide.value<TableProvide>(context).contextList),
                  ),
          ).toList()
      );
      List<DataCell> _getCells(List<String> keyList,data,contextList) {

    List<DataCell> cells = [];

    cells.add(
     //因为前面的操作符是通过状态管理进行控制的,所以我们要单独的插入到cells
      DataCell(
        Text('${Provide.value<TableProvide>(context).openState[data]['symbol']}'),
        onTap: (){
          Provide.value<TableProvide>(context).openNum=data;
          Provide.value<TableProvide>(context).changeOpenState();
        }
    ));
	//利用key的数量,动态生产几列
    keyList.forEach((key) {
      cells.add(DataCell(
        Text('${contextList[data][key]}'),
      ));
    });

    return cells;
  }

请求接口和调用表格函数

		child: FutureBuilder(
          future: _getInfo(context),     //调用请求方法
          builder: (context,snapshot){             
            if(snapshot.hasData){                      //判断是否有返回值
              return Center(
                child: new ListView(
                  children: <Widget>[
                    Provide<TableProvide>(
                    builder: (context,child,val){
                      return Container(
                        child:tableContext(),
                      );
                    }),
                  ],
                ),
              );
            }else{
              return Center(
                child:Text('加载中')
              );
            }
            },
        ),

页面完整代码

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provide/provide.dart';
import '../provide/table.dart';

class CommodityPage extends StatefulWidget {
  CommodityPage({Key key}) : super(key: key);

  _CommodityPageState createState() => _CommodityPageState();
}

class _CommodityPageState extends State<CommodityPage> {


  @override
  Widget build(BuildContext context) {
    ScreenUtil.instance=ScreenUtil(width: 750, height: 1334)..init(context);
    return Scaffold(
      appBar: AppBar(title: Text('测试'),),
      body:Container(
        child: FutureBuilder(
          future: _getInfo(context),     //调用请求方法
          builder: (context,snapshot){             
            if(snapshot.hasData){                      //判断是否有返回值
              return Center(
                child: new ListView(
                  children: <Widget>[
                    Provide<TableProvide>(
                    builder: (context,child,val){
                      return Container(
                        child:tableContext(),
                      );
                    }),
                  ],
                ),
              );
            }else{
              return Center(
                child:Text('加载中')
              );
            }
            },
        ),
      ),
    );
  }

  Widget tableContext(){
    return new DataTable(
          columns: Provide.value<TableProvide>(context).titleList.map((data)=>DataColumn(
            label: Text(data)
          )).toList(),  
          rows: Provide.value<TableProvide>(context).contextNum.map((data)=>
                  DataRow(
                    cells:  _getCells(Provide.value<TableProvide>(context).keyList,data,Provide.value<TableProvide>(context).contextList),
                  ),
          ).toList()
      );
  }

  List<DataCell> _getCells(List<String> keyList,data,contextList) {

    List<DataCell> cells = [];

    cells.add(
      DataCell(
        Text('${Provide.value<TableProvide>(context).openState[data]['symbol']}'),
        onTap: (){
          Provide.value<TableProvide>(context).openNum=data;
          Provide.value<TableProvide>(context).changeOpenState();
        }
    ));

    keyList.forEach((key) {
      cells.add(DataCell(
        Text('${contextList[data][key]}'),
      ));
    });

    return cells;
  }

  Future _getInfo(BuildContext context) async{
    await Provide.value<TableProvide>(context).getTableInfo();
    return '加载完毕';
  }
}

大家模拟一下数据,就可以进行测试了,希望可以帮助到大家

发布了50 篇原创文章 · 获赞 35 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_35905501/article/details/91043511