方式1
    image.png
    代码

    1. import 'package:eam_page/smartbubble/smart_bubble_widget.dart';
    2. import 'package:flutter/cupertino.dart';
    3. import 'package:flutter/material.dart';
    4. import 'package:flutter_screenutil/flutter_screenutil.dart';
    5. import 'bubble.dart';
    6. class ApprovalRecord extends StatelessWidget {
    7. ApprovalRecord({Key key}) : super(key: key);
    8. List<Map<String,String>> _list = [
    9. {'des':'流程审批内容', 'person':'张三', 'date':'2021-11-12'},
    10. {'des':'流程审批内容2啊实打实阿松大啊阿松大阿啊实打实松大阿萨伟大啊飒飒的实打实的啊啊十大阿松大飒飒的', 'person':'王五', 'date':'2021-12-12'},
    11. {'des':'流程审批内容3', 'person':'赵六', 'date':'2021-12-20'}
    12. ];
    13. @override
    14. Widget build(BuildContext context) {
    15. return Scaffold(
    16. appBar: AppBar(title: Text('审批流程'),),
    17. body: Container(
    18. margin: EdgeInsets.only(top: 20),
    19. child: Column(
    20. children: List.generate(this._list.length, (index) {
    21. return Container(
    22. width: double.infinity,
    23. child: Stack(
    24. children: [
    25. Container(
    26. padding: EdgeInsets.only(left: 20, bottom: 10,top: 10),
    27. margin: EdgeInsets.only(left: 20),
    28. decoration: BoxDecoration(
    29. border: Border(
    30. //绘制左边的线
    31. left: BorderSide(
    32. //绘制边框线,最后一个不绘制
    33. color: index == this._list.length -1 ? Colors.white : Colors.blue,
    34. width: 1,
    35. ),
    36. ),
    37. ),
    38. //右边的内容
    39. child: CustomPaint(
    40. painter: _MyPainter(
    41. color: Colors.blue
    42. ),
    43. child: Container(
    44. width: ScreenUtil().setWidth(500),
    45. padding: EdgeInsets.all(3),
    46. decoration: BoxDecoration(
    47. borderRadius: BorderRadius.all(Radius.circular(5.0)),
    48. ),
    49. child: Column(
    50. crossAxisAlignment: CrossAxisAlignment.start,
    51. children: [
    52. Row(
    53. mainAxisAlignment: MainAxisAlignment.spaceBetween,
    54. children: [
    55. Container(
    56. //margin: EdgeInsets.only(left: 5.0,top: 5.0),
    57. child: Text('操作人:${_list[index]['person']}',style: TextStyle(fontSize: 10.0)),
    58. ),
    59. Container(
    60. //margin: EdgeInsets.only(left: 5.0,top: 5.0),
    61. child: Text('时间:${_list[index]['date']}',style: TextStyle(fontSize: 10.0)),
    62. ),
    63. ],
    64. ),
    65. Container(
    66. //color: Colors.black,
    67. //margin: EdgeInsets.only(right: 140.0),
    68. child: Text(
    69. _list[index]['des'],
    70. style: TextStyle(
    71. //color: Colors.white,
    72. fontSize: 12.0,
    73. )
    74. ),
    75. ),
    76. ],
    77. ),
    78. ),
    79. )
    80. ),
    81. //状态圆点
    82. Positioned(
    83. left: 5.6,
    84. top: -2,
    85. child: Container(
    86. width: ScreenUtil().setWidth(40),
    87. height: ScreenUtil().setHeight(45),
    88. color: Colors.white,
    89. //decoration: BoxDecoration(color: Colors.white),
    90. child: Container(
    91. child: Icon(Icons.assignment_ind,color: Colors.blue,size: 30),
    92. ),
    93. //child: Icon(Icons.assignment_ind,color: Colors.blue,size: 30),
    94. ),
    95. ),
    96. ],
    97. ),
    98. );
    99. })
    100. )
    101. ),
    102. );
    103. }
    104. }
    105. //自定义文件框
    106. class _MyPainter extends CustomPainter {
    107. final Color color;
    108. _MyPainter({this.color});
    109. @override
    110. void paint(Canvas canvas, Size size) {
    111. Paint paint = Paint()..color = color ..strokeWidth = 1.5;
    112. //上边的线
    113. canvas.drawLine(Offset(0 ,0), Offset(size.width,0), paint);
    114. //底部线
    115. canvas.drawLine(Offset(0 ,size.height), Offset(size.width,size.height), paint);
    116. //左上边线
    117. canvas.drawLine(Offset(0 ,size.height / 2 - 6 ), Offset(0,0), paint);
    118. //左下边线
    119. canvas.drawLine(Offset(0 ,size.height), Offset(0, size.height / 2 + 6 ), paint);
    120. //右边线
    121. canvas.drawLine(Offset(size.width ,0), Offset(size.width,size.height), paint);
    122. //三角箭头上边的线
    123. canvas.drawLine(Offset(-8 ,size.height / 2), Offset(0,size.height / 2 - 6), paint);
    124. //三角箭头下边的线
    125. canvas.drawLine(Offset(-8 ,size.height / 2), Offset(0,size.height / 2 + 6), paint);
    126. }
    127. @override
    128. bool shouldRepaint(covariant _MyPainter oldDelegate) => false;
    129. }

    方式2
    image.png
    调取
    image.png

    import 'package:eam_page/smartbubble/smart_bubble_widget.dart';
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_screenutil/flutter_screenutil.dart';
    import 'bubble.dart';
    
    class ApprovalRecord extends StatelessWidget {
    
      List<Map<String,String>> list;
      ApprovalRecord({ Key key,@required this.list}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return ListView.builder(
            itemCount: this.list.length,
            itemBuilder: (context, index){
              return AppInfo(map: list[index], index: index,);
            }
        );
      }
    }
    
    class AppInfo extends StatefulWidget {
    
      Map<String,String> map;
      int index;
      AppInfo({@required this.map, @required this.index, Key key}) : super(key: key);
    
      @override
      _AppInfo createState() => _AppInfo(map: map);
    }
    
    class _AppInfo extends State<AppInfo> {
    
      Map<String,String> map;
    
      _AppInfo({@required this.map}) ;
    
      double item_height = 0.0;
    
      GlobalKey textKey = new GlobalKey();
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        // 监听是否渲染完
        WidgetsBinding widgetsBinding = WidgetsBinding.instance;
        widgetsBinding.addPostFrameCallback((callback) {
          //获取相应控件的size
          RenderObject renderObject =textKey.currentContext.findRenderObject();
          setState(() {
            item_height = renderObject.semanticBounds.size.height;
          });
    
        });
    
      }
    
      @override
      Widget build(BuildContext context) {
    
        return Container(
          color: Colors.white,
          padding: EdgeInsets.only(left: 20, right: 10),
          child: Row(
            children: [
              //左侧的线
              Container(
                margin: EdgeInsets.only(left: 20),
                width: 10,
                height: item_height,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Expanded(
                      child: Container(
                        width: 0.9,
                        color: Colors.blue,
                      ),
                    ),
                    Container(
                      height: 10,
                      width: 10,
                      decoration: BoxDecoration(
                        color: Colors.blue,
                        borderRadius:BorderRadius.all(Radius.circular(5)),
                      ),
                    ),
                    Expanded(
                        child: Container(
                          width: 0.9,
                          color: Colors.blue,
                        )
                    ),
                  ],
                ),
              ),
    
              //右侧的内容
              Expanded(
                  child: Padding(
                    key:textKey,
                    padding:const EdgeInsets.only(left:20,top: 5,bottom: 5),
                    child: CustomPaint(
                      painter: _MyPainter(
    
                          color: Colors.blue
                      ),
                      child: Container(
                        width: ScreenUtil().setWidth(500),
                        padding: EdgeInsets.all(3),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: [
                                  Container(
                                    //margin: EdgeInsets.only(left: 5.0,top: 5.0),
                                    child: Text('操作人:${map['person']}',style: TextStyle(fontSize: 10.0)),
                                  ),
                                  Container(
                                    //margin: EdgeInsets.only(left: 5.0,top: 5.0),
                                    child: Text('时间:${map['date']}',style: TextStyle(fontSize: 10.0)),
                                  ),
                                ],
                              ),
                              Container(
                                //color: Colors.black,
                                //margin: EdgeInsets.only(right: 140.0),
                                child: Text(
                                    map['des'],
                                    style: TextStyle(
                                      //color: Colors.white,
                                      fontSize: 12.0,
                                    )
                                ),
                              ),
                            ]
                        ),
                      ),
                    )
    
                  )
              ),
            ],
            //右侧的文案
          ),
        );
      }
    }
    
    
    //自定义文件框
    class _MyPainter extends CustomPainter {
    
      final Color color;
      _MyPainter({this.color});
    
      @override
      void paint(Canvas canvas, Size size) {
    
        Paint paint = Paint()..color = color ..strokeWidth = 1.5;
        //上边的线
        canvas.drawLine(Offset(0 ,0), Offset(size.width,0), paint);
        //底部线
        canvas.drawLine(Offset(0 ,size.height), Offset(size.width,size.height), paint);
        //左上边线
        canvas.drawLine(Offset(0 ,size.height / 2 - 6 ), Offset(0,0), paint);
        //左下边线
        canvas.drawLine(Offset(0 ,size.height), Offset(0, size.height / 2 + 6 ), paint);
        //右边线
        canvas.drawLine(Offset(size.width ,0), Offset(size.width,size.height), paint);
    
        //三角箭头上边的线
        canvas.drawLine(Offset(-8 ,size.height / 2), Offset(0,size.height / 2 - 6), paint);
        //三角箭头下边的线
        canvas.drawLine(Offset(-8 ,size.height / 2), Offset(0,size.height / 2 + 6), paint);
      }
    
      @override
      bool shouldRepaint(covariant _MyPainter oldDelegate) => false;
    
    }