前言
学习flutter差不多用了一个月的时间,刚好最近公司启动了一个新项目,本人决定使用flutter开发,两个星期写UI两个星期写接口,现在已经进入测试阶段,总结一下项目中值得记录的部分
UI效果图
flutter实现效果图
其实也就是中间那部分该如何实现的问题?
具体实现
- 分析
- 每个item 对应为row 一行
- 这个 row 分为左右结构,如图蓝色部分
为了简化代买,我把项目中的代码拆出来,写了demo,下面的代码可以直接复制到demo中可直接运行
代码实现
import 'dashed_line_widget.dart';
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
List<String>dataList = [
'这些年, 习近平主席视察部队时接见最多的是基层一线官兵, 从北疆哨所到南国林海, 从戈壁大漠到海防一线, 习主席每次走进基层总是与士兵亲切交谈, 他很关心战士们的生活, 拉家常、 问冷暖。 对官兵, 习主席有一种天然的亲近感。 他年轻时在军队工作过一段时间, 在担任地方领导期间十分关心支持国防和军队建设, 曾深情赋诗“ 难得举城作一庆, 爱我人民爱我军',
'习近平主席多次强调:“ 实现强军目标, 基础在基层, 活力也在基层。” 基层是部队建设和战斗力的基础。 党的十八大以来, 习主席数十次深入基层部队视察调研, 踏冰雪、 冒严寒、 到一线, 基层战士始终是习主席心中最深的牵挂。',
'潜客状态变化'
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body:_grayCenter(context),
);
}
//灰色部分
Widget _grayCenter(BuildContext context){
List<Widget> widgets = [];
for(String followupList in dataList){
Widget widget = _getRow(followupList);
widgets.add(widget);
}
print(widgets);
return Container(
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFFF7F9FA),
borderRadius: BorderRadius.circular(3),
),
padding: EdgeInsets.only(left: 0,right: 15,top: 15,bottom: 15),
child: Column(
children:widgets,
),
);
}
Widget _getRow(String followupListItem){
String timestr = DateTime.now().toString().substring(0,10);
Widget firstRow;
Widget contentWidget = SizedBox();
//跟进记录
contentWidget = Text(
followupListItem??"--",
style: TextStyle(
fontSize: 12,
),
softWrap: true,
);
firstRow = Row(
children: <Widget>[
Text(
timestr,
style: TextStyle(
fontSize: 12.0,
)
)
],
);
Widget pointWidget;
double topSpace = 0;
topSpace = 3;
pointWidget = ClipOval(
child: Container(
width: 7,
height: 7,
color: Colors.grey,
),
);
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//灰色右
Expanded(
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 37),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: topSpace==0?4:0,
),
firstRow,
SizedBox(
height: 12.0,
),
contentWidget,
SizedBox(
height: 12.0,
),
],
),
),
Positioned(
left: 0,
width: 37,
bottom: 0,
top: topSpace,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
pointWidget,
Expanded(
child: Container(
width: 27,
child: MySeparatorVertical(
color: Colors.grey,
),
),
)
],
),
),
)
],
),
),
],
);
}
}
dashed_line_widget.dart
import 'package:flutter/material.dart';
class MySeparatorVertical extends StatelessWidget {
final Color color;
const MySeparatorVertical({this.color = Colors.black});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final height = constraints.constrainHeight();
final dashWidth = 4.0;
final dashCount = (height / (2 * dashWidth)).floor();
print("dashCount $dashCount height $height");
return Flex(
children: List.generate(dashCount, (_) {
return SizedBox(
width: 1,
height: dashWidth,
child: DecoratedBox(
decoration: BoxDecoration(color: color),
),
);
}),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
direction: Axis.vertical,
);
},
);
}
}
运行出来的效果
总结
- 其实就是利用了stack 与 position 的特性自动获取右侧文字的大小
- LayoutBuilder 获取constraints 大小