flutter书架形式格口的动态创建(行、列数,是否全选的配置)

文章描述了一个使用Dart编写的Flutter应用,用户可以创建不同格口数量的书架,并能批量设置和选择格口规格,包括查看尺寸、填写尺寸和上架/下架操作。

根据传入的行列数创建不同格口数量的书架
左图:5行3列、右图:3行3列
在这里插入图片描述在这里插入图片描述
代码

import 'package:jade/bean/experienceStation/ExpCellSpecsBean.dart';
import 'package:jade/configs/PathConfig.dart';
import 'package:jade/utils/DialogUtils.dart';
import 'package:jade/utils/JadeColors.dart';
import 'package:jade/utils/Utils.dart';
import 'package:util/navigator_util.dart';
import 'package:widget/custom_appbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

class ExperienceStationCreateCellSpecsSet extends StatefulWidget{

  final int rowCount; //行数
  final int columnCount; //列数
  const ExperienceStationCreateCellSpecsSet({this.rowCount,this.columnCount});

  
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _ExperienceStationCreateCellSpecsSet();
  }
}

class _ExperienceStationCreateCellSpecsSet extends State<ExperienceStationCreateCellSpecsSet>{

  String _latticeImage = PathConfig.imageLatticeCenter;
  List<List<ExpCellSpecsBean>> _expCellSpecsList = [];

  //判断全选
  static bool _isSelectAll = false;

  //判断是否是全选或批量设置状态
  bool _isSelectAllBatch = false;

  
  void initState() {
    // TODO: implement initState
    super.initState();
    _setList();
  }




  
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      resizeToAvoidBottomInset: false,
      backgroundColor: JadeColors.lightGrey,
      appBar: CustomAppBar(
        backgroundColor: Colors.white,
        elevation: 0.2,
        leading: GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: Icon(Icons.arrow_back_ios),
        ),
        iconTheme: IconThemeData(color: Color(0xff999999)),
        title: Text(
          '格口规格',
          style: TextStyle(color: Colors.black),
        ),
        centerTitle: true,
      ),
      body: _body(),
    );
  }

  _body(){
    return Container(
      margin: EdgeInsets.only(top: 100.w,left: 50.w),
      child: Column(
        children: [
          _selectBtnView(),
          _bookRackView(),
          _sureBtn()
        ],
      )
    );
  }

  _selectBtnView(){
    return Row(
      children: [
        GestureDetector(
          child: Container(
            height: 45.w,
            padding: EdgeInsets.symmetric(horizontal: 20.w),
            alignment: Alignment.center,
            margin: EdgeInsets.only(right: 30.w),
            decoration: BoxDecoration(
              color: _judgeSelectAll() ? JadeColors.grey_10 : JadeColors.blue_2,
              borderRadius: BorderRadius.circular(10)
            ),
            child: Text(_judgeSelectAll() ? '取消':'全选',style: TextStyle(color: Colors.white,fontSize: 22.sp),),
          ),
          onTap: (){
            _setSelectAll();
          }
        ),
        GestureDetector(
            child: Container(
              height: 45.w,
              alignment: Alignment.center,
              padding: EdgeInsets.symmetric(horizontal: 20.w),
              decoration: BoxDecoration(
                  color: JadeColors.blue_2,
                  borderRadius: BorderRadius.circular(10)
              ),
              child: Text('批量设置',style: TextStyle(color: Colors.white,fontSize: 22.sp),),
            ),
            onTap: (){
              DialogUtils().fillInCellInfoDialog(context,
                  sureCallBack: (result) {
                    ExpCellSpecsBean resultBean = result;
                    ///todo 循环赋给选中的格口
                    //_expCellSpecsList[row][column]
                    setState(() {});
                  });
            }
        )
      ],
    );
  }

  _bookRackView(){
    return Container(
      margin: EdgeInsets.only(top: 40.w,bottom: 40.w),
      width: Utils().screenWidth(context)- 60.w,
      height: Utils().screenHeight(context) * 0.6,
      child: InteractiveViewer(
          constrained: false,
          scaleEnabled: false,
          child: Table(
            columnWidths: <int, TableColumnWidth>{
              for (int column = 0; column < widget.columnCount; column += 1)
                column: const FixedColumnWidth(110),
            },
            children: buildRows(widget.rowCount, widget.columnCount),
          )
      ),
    );
  }

  List<TableRow> buildRows(int rowCount, int columnCount) {
    return [
      for (int row = 0; row < rowCount; row += 1)
        TableRow(
          children: [
            for (int column = 0; column < columnCount; column ++)
              InkWell(
                child: Container(
                  height: 190.w,
                  decoration: BoxDecoration(
                    image:DecorationImage(
                      image: AssetImage(_setLatticeImage(row,column)),
                      fit: BoxFit.fill, // 完全填充
                    ),
                  ),
                  child: Stack(
                    children: [
                      Container(
                          alignment: Alignment.center,
                          margin: EdgeInsets.only(
                            top: row == widget.rowCount -1 ? 0 : 30.w,
                            left: column == 0 ? 30.w : 0,
                            right: column == widget.columnCount -1 ? 20.w : 0,
                          ),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              GestureDetector(
                                child: Container(
                                  padding: EdgeInsets.only(left: 20.w,right: 20.w,top: 6.w,bottom: 6.w),
                                  decoration: BoxDecoration(
                                    color: _isCellFillInfo(_expCellSpecsList[row][column]) ? JadeColors.blue_2 : Colors.white38,
                                    borderRadius: BorderRadius.circular(20),
                                    border: Border.all(width: 1,color: JadeColors.blue_2)
                                  ),
                                  child: Text(_isCellFillInfo(_expCellSpecsList[row][column]) ? '查看尺寸':'填写尺寸',
                                    style: TextStyle(color: _isCellFillInfo(_expCellSpecsList[row][column]) ? Colors.white : JadeColors.blue_2,fontSize: 24.sp),),
                                ),
                                onTap: (){
                                  DialogUtils().fillInCellInfoDialog(context,
                                      viewedExpCellSpecsBean: _isCellFillInfo(_expCellSpecsList[row][column])
                                            ? _expCellSpecsList[row][column]
                                            : null,
                                      sureCallBack: (result) {
                                      ExpCellSpecsBean resultBean = result;
                                      _expCellSpecsList[row][column].cellHeight = resultBean.cellHeight;
                                      _expCellSpecsList[row][column].cellWidth = resultBean.cellWidth;
                                      _expCellSpecsList[row][column].cellDepth = resultBean.cellDepth;
                                      _expCellSpecsList[row][column].cellPic = resultBean.cellPic;
                                      print('填写后的回填:${_expCellSpecsList[row][column].toJson()}');
                                      setState(() {});
                                    });
                                  }
                              ),
                              SizedBox(height: 10.w),
                              GestureDetector(
                                  child: Container(
                                    padding: EdgeInsets.only(left: 20.w,right: 20.w,top: 6.w,bottom: 6.w),
                                    decoration: BoxDecoration(
                                        color: _expCellSpecsList[row][column].cellPublishStatus == 1 ? Colors.white38 : JadeColors.blue_2,
                                        borderRadius: BorderRadius.circular(20),
                                        border: Border.all(width: 1,color: JadeColors.blue_2)
                                    ),
                                    child: Text(_expCellSpecsList[row][column].cellPublishStatus == 1 ? '下架格口' : '上架格口',
                                      style: TextStyle(color: _expCellSpecsList[row][column].cellPublishStatus == 1 ? JadeColors.blue_2 : Colors.white,fontSize: 24.sp),),
                                  ),
                                  onTap: (){
                                    if(_expCellSpecsList[row][column].cellPublishStatus == 1){
                                      DialogUtils().commonDescDialog(context,
                                          descTitle: '下架格口',
                                          desc: '下架后该格口将不能进行交易、售卖。',
                                          showCancel: true,
                                          sureBtnText: '确认下架',
                                          sureBtnTextColor: JadeColors.grey_2,
                                          callback: (){
                                            setState(() {
                                              _expCellSpecsList[row][column].cellPublishStatus = 0;
                                            });
                                          }
                                      );
                                    }else{
                                      setState(() {
                                        _expCellSpecsList[row][column].cellPublishStatus = 1;
                                      });
                                    }

                                  }
                              ),
                            ],
                          )
                      ),
                      GestureDetector(
                        child: Container(
                          padding: EdgeInsets.only(left: 2,top: 1,right: 5,bottom: 5),
                          color: Colors.transparent,
                          child: Container(
                            width: 36.w,
                            height: 36.w,
                            alignment: Alignment.center,
                            margin: EdgeInsets.only(top: 14.w,left: 10.w),
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(4),
                                border: Border.all(width: 1.w,color: Colors.white),
                                color: _expCellSpecsList[row][column].isSelected ? JadeColors.blue_2 : JadeColors.translucent
                            ),
                            child: _expCellSpecsList[row][column].isSelected ? Image.asset(PathConfig.iconCheckWhite,width: 20.w,height: 20.w) : Text('${_expCellSpecsList[row][column].num}',style: TextStyle(color: Colors.white,fontSize: 15.sp,fontWeight: FontWeight.bold)),
                          ),
                        ),
                        onTap: (){
                          setState(() {
                            _expCellSpecsList[row][column].isSelected = !_expCellSpecsList[row][column].isSelected;
                          });
                          _isSelectAll = _judgeSelectAll();
                        }
                      )
                    ],
                  ),
                ),
                onTap: (){},
              )
          ],
        ),
    ];
  }

  String _setLatticeImage(row,column){
    if(row == 0 && column == 0){
      //左上角
      _latticeImage = PathConfig.imageLatticeTopLeft;

    }else if(row == 0 && column == widget.columnCount-1){
      //右上角
      _latticeImage = PathConfig.imageLatticeTopRight;

    }else if(row == widget.rowCount -1 && column == 0){
      //左下角
      _latticeImage = PathConfig.imageLatticeBottomLeft;
    }else if(row == widget.rowCount -1 && column == widget.columnCount-1){
      //右下角
      _latticeImage = PathConfig.imageLatticeBottomRight;
    }else if(column==0){
      _latticeImage = PathConfig.imageLatticeSecondLeft;
    }else if(column== widget.columnCount-1){
      _latticeImage = PathConfig.imageLatticeSecondRight;
    }else if(row == widget.rowCount -1){
      _latticeImage = PathConfig.imageLatticeSecondBottom;
    }else {
      _latticeImage = PathConfig.imageLatticeCenter;
    }

    return _latticeImage;
  }

  _sureBtn(){
    return GestureDetector(
      child: Container(
        height: 80.w,
        width: Utils().screenWidth(context) * 0.6,
        alignment: Alignment.center,
        decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(50),
            color: JadeColors.blue_2,
            boxShadow: [BoxShadow(color: JadeColors.blue_8,blurRadius: 3.0,offset: Offset(0.0, 3.0),)]
        ),
        child: Text('确定',style: TextStyle(color: Colors.white,fontSize: 34.sp,fontWeight: FontWeight.w600)),
      ),
      onTap: (){
        NavigatorUtil.pop(value: _expCellSpecsList);
      }
    );
  }

  //根据行数、列数配置初始二维数组
  _setList(){
    for (int i = 0; i < widget.rowCount; i++) {
      // 对于每一行,创建一个新的列表来存放该行的列数据
      List<ExpCellSpecsBean> rowData = [];
      // 在该行的每一列中添加数据
      for (int j = 0; j < widget.columnCount; j++) {
        //计算序号
        int _number = (i * widget.columnCount) + (j + 1);
        ExpCellSpecsBean cellSpecs = ExpCellSpecsBean(
            num: _number
        );
        // 将该数据添加到当前行的列表中
        rowData.add(cellSpecs);
      }
      // 将当前行的列表添加到总列表中
      _expCellSpecsList.add(rowData);
    }

    for (var row in _expCellSpecsList) {
      for (var cell in row) {
        print('Cell number: ${cell.num}'); // 输出每个CellsBean的序号
      }
    }
  }

  //设置全选
  _setSelectAll(){
    for (var row in _expCellSpecsList) {
      for (var cell in row) {
        if(_isSelectAll){
          cell.isSelected = false;
        }else{
          cell.isSelected = true;
        }
      }
    }
    _isSelectAll = !_isSelectAll;
    setState(() {});
  }

  //判断是否全选
  bool _judgeSelectAll(){
    for (var row in _expCellSpecsList) {
      for (var cell in row) {
        if(!cell.isSelected){
          return false;
        }
      }
    }
    return true;
  }

  //判断某格口是否已填写了尺寸信息
  bool _isCellFillInfo(ExpCellSpecsBean bean){
    if(bean.cellHeight != null || bean.cellWidth != null || bean.cellDepth != null || bean.cellPic != null){
      return true;
    }else{
      return false;
    }
  }

}

调用

var result = await NavigatorUtil.push(ExperienceStationCreateCellSpecsSet(rowCount: state.rowCount,columnCount: state.columnCount));
            if(result != null){
            //TODO处理逻辑
            }

书架格子背景图

1.左上角背景
左上角
2.右上角背景
右上角的
3.左下角背景
在这里插入图片描述
4.右下角背景
在这里插入图片描述
5.中段左侧背景
在这里插入图片描述
6.中段右侧背景
在这里插入图片描述
7.最后一行左下角、右下角中间格子的背景
在这里插入图片描述
8.左上角、右上角中间格子及书架中间部分格子的背景
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值