美文网首页
Flutter 流程图布局

Flutter 流程图布局

作者: fordG | 来源:发表于2020-08-11 14:10 被阅读0次
    • 需求就是根据右边文字自适应高度来画流程图,左边灰色的线有长有短,两头的线不能超出这么一个续修, 我试直接用container套column套row最外层是不设置高度, 要不无法做到自适应高度, 通过获取右边文字的高度来画线,达到图上面的效果

    重点需求在自适应高度, 不能设置高度, 线第一个和最后一个两头不能有###

    一开始想不去获取高度,通过自适应来画出线来, 没找到办法, 有指导的麻烦代码教教我!

    • 获取高度 用的callback回调通知父widget
    
    import 'package:bgbz/net/net.dart';
    import 'package:flutter/material.dart';
    
    typedef CallBackHeight = void Function(double value);
    class HeightReporter extends StatelessWidget {
      final Widget child;
      CallBackHeight callBackHeight;
    
      HeightReporter({this.child});
      double _height;
      double getHeight() {
        return _height;
      }
    
      @override
      Widget build(BuildContext context) {
        Widget tmp = new GestureDetector(
          child: child,
          onTap: () {
            print('Height is ${context.size.height}');
          },
        );
    
        Net.delay(200, (){
          _height = context.size.height;
          if(callBackHeight != null){
            callBackHeight(context.size.height);
          }
        });
        return tmp;
      }
    }
    
    
    • 单个流程图, 用的是自己的数据, 测试可以替换
    import 'package:bgbz/components/height_reporter.dart';
    import 'package:bgbz/utils/style.dart';
    import 'package:flutter/material.dart';
    import 'package:bgbz/model/detail/log_info.dart';
    
    enum FlowWidthStyle {
      all,
      top,
      bottom,
    }
    
    enum FlowWidthStatus{
      done,
      ready
    }
    
    class FlowWidth extends StatefulWidget {
      final LogInfo logInfo;
      final FlowWidthStyle flowStyle; //两端线都需要
      final FlowWidthStatus flowStatus; //状态
    
      FlowWidth({this.logInfo, this.flowStyle, this.flowStatus});
      @override
      _FlowWidthState createState() => _FlowWidthState();
    }
    
    class _FlowWidthState extends State<FlowWidth> {
      double defaultHeight = 10;
      double screenWidth;
      double circleWidth = 5;
      @override
      Widget build(BuildContext context) {
        screenWidth = MediaQuery.of(context).size.width;
        return Container(
          color: Colors.white,
          margin: EdgeInsets.only(top: 0, left: 15, right: 15),
          width: screenWidth - 30,
          child: Container(
            child: Row(
              children: [
                Container(
                  width: 5,
                  height: defaultHeight,
                  child: Column(
                    children: _childsWidget(),
                  ),
                ),
                Container(
                  padding: EdgeInsets.only(left: 10),
                  width: 90,
                  child: Text(
                      widget.logInfo.bWF_CurOperatorTime.replaceAll('-', '.'),
                      style: Style.cnNameTitle),
                ),
                _fitChild(widget.logInfo)
              ],
            ),
          ),
        );
      }
    
      Widget _fitChild(LogInfo logInfo) {
        HeightReporter heightReporter = HeightReporter(
            child: Container(
          width: screenWidth - 140,
          padding: EdgeInsets.only(left: 10, top: 10, bottom: 10),
          child: Text(logInfo.bWF_CurUsername + '\t' + logInfo.bWF_Opinion,
              style: Style.detailValueTitle),
        ));
        if(defaultHeight == 10){
          heightReporter.callBackHeight = (double height) {
            setState(() {
              defaultHeight = height;
            });
          };
        }
    
        return heightReporter;
      }
    
      Widget _line() {
        return Container(
          height: (defaultHeight - circleWidth) / 2,
          width: 2,
          color: Style.lineColor,
        );
      }
    
      Widget _circle() {
        return Container(
          height: 5,
          width: 5,
          decoration: BoxDecoration(
              color: widget.flowStatus == FlowWidthStatus.done ? Colors.black38 : Colors.blue, borderRadius: BorderRadius.circular(2.5)),
        );
      }
    
      List<Widget> _childsWidget() {
        if (widget.flowStyle == FlowWidthStyle.all) {
          return [_line(), _circle(), _line()];
        } else if (widget.flowStyle == FlowWidthStyle.top) {
          return [Padding(padding: EdgeInsets.only(top: (defaultHeight - circleWidth) / 2), child: _circle()), _line()];
        } else {
          return [_line(), _circle()];
        }
      }
    }
    
    
    • 使用的时候
    
    Column
    
    if((index - 1) == 0)
                    return FlowWidth(logInfo: list[index - 1], flowStyle: FlowWidthStyle.top, flowStatus: FlowWidthStatus.ready);
                  else if((index) == list.length)
                    return FlowWidth(logInfo: list[index - 1], flowStyle: FlowWidthStyle.bottom, flowStatus: FlowWidthStatus.done);
                  else
                    return FlowWidth(logInfo: list[index - 1], flowStyle: FlowWidthStyle.all, flowStatus: FlowWidthStatus.done);
                }
    

    相关文章

      网友评论

          本文标题:Flutter 流程图布局

          本文链接:https://www.haomeiwen.com/subject/lqtydktx.html