Flutter通过Container实现时间轴效果
作者:码农王真实 发布时间:2023-10-04 09:40:45
标签:Flutter,Container,时间轴
目录
时间轴是前端UI经常用到的效果,先看下效果图:
实现
一、借助 Container 中 decoration 属性,设置左侧的 border,可以实现时间轴高度随着 item 变化效果
二、重写 BorderDirectional 中 paint 方法
三、完整代码
时间轴是前端UI经常用到的效果,先看下效果图:
时间轴的特点
1、在列表中的高度不确定,高度取决于右侧 item 的高度
2、时间轴通常在第一个 item 中的样式和其他 item 中不同。
实现
一、借助 Container 中 decoration 属性,设置左侧的 border,可以实现时间轴高度随着 item 变化效果
Center(
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
// 设置 BoxDecoration 的 border, border 的高度就是 Container 的高度
border: Border(left: BorderSide(color: Colors.red)),
color: Color(0x11000000),
),
))
效果 (图中红线是 Container 左侧的 border,可以在这里扩展成 timeline) :
二、重写 BorderDirectional 中 paint 方法
BorderDirectional 中原来的 paint 方法,可以看出,设置不同的属性,会调用不同的绘制方法实现不同的效果,这里重新 paint 方法,实现时间轴的效果
paint 方法中参数
canvas : 这个就是画布了,借助这个 canvas 可以随意实现各种效果
rect : Container 的范围大小
我们的 paint 方法实现,按照 UI 设计图,对应的位置画上圆和线就可以了
@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection, BoxShape shape = BoxShape.rectangle, BorderRadius? borderRadius}) {
if (position != 1) {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top), Offset(rect.left +margin+ radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius,_strokePaint());
} else {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), Offset(rect.left+margin + radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius / 2, _strokePaint());
}
}
最终效果
三、完整代码
class BorderTimeLine extends BorderDirectional {
int position;
BorderTimeLine(this.position);
double radius = 10;
double margin= 20;
Paint _paint = Paint()
..color = Color(0xFFDDDDDD)
..strokeWidth = 1;
@override
void paint(Canvas canvas, Rect rect, {TextDirection? textDirection, BoxShape shape = BoxShape.rectangle, BorderRadius? borderRadius}) {
if (position != 0) {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top), Offset(rect.left +margin+ radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius,_strokePaint());
} else {
canvas.drawLine(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), Offset(rect.left+margin + radius / 2, rect.bottom), _strokePaint());
canvas.drawCircle(Offset(rect.left+margin + radius / 2, rect.top + radius * 2), radius, _fillPaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius, _strokePaint());
canvas.drawCircle(Offset(rect.left +margin+ radius / 2, rect.top + radius * 2), radius / 2, _strokePaint());
}
}
Paint _fillPaint(){
_paint.color=Colors.white;
_paint.style=PaintingStyle.fill;
return _paint;
}
Paint _strokePaint(){
_paint.color=Color(0xFFDDDDDD);
_paint.style=PaintingStyle.stroke;
return _paint;
}
}
在 ListView 中的 item 中使用
Widget _buildItem(BuildContext c, int i) {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(border: BorderTimeLine(i)),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [
Padding(padding: EdgeInsets.symmetric(vertical: 10)),
Divider(color: Colors.grey.shade300, thickness: 40),
Text("$i" * 6, style: TextStyle(color: Colors.black, fontSize: 16)),
Text("abc\n" * Random().nextInt(10)),
Padding(padding: EdgeInsets.symmetric(vertical: 10)),
]),
));
}
全部代码 github
来源:https://juejin.cn/post/6963476792669634590


猜你喜欢
- Android开发环境有三种方式,分别是JDK+SDK+Eclipse+ADT、JDK+adt-bundle与JDK+Android Stu
- 使用INI配置文件,简单便捷。该辅助工具类为C#操作INI文件的辅助类,源码在某位师傅的基础上完善的来,因为忘记最初的来源了,因此不能提及引
- 前言对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿
- Atomikos是一个为Java平台提供增值服务的并且开源类事务管理器,如果将事务统一注册到Atomikos中,则可以统一管理。常用于后台管
- 文件切割和文件合并这个问题困扰了我有一段时间了(超过一天没做粗来)。找了好多博客,本来想转载一个来的 结果找不到了。很无奈。只好自己贴代码上
- 开发环境: IDEA 2022.1.41. 概述虽然webservice这块使用很少,但在局域网作服务还是相当不错。今天突生想法,想做一个来
- List集合相信大家在开发过程中几乎都会用到。有时候难免会遇到集合里的数据是重复的,需要进行去除。然而,去重方式有好几种方式,你用的是哪种方
- 1、UUID类库UUID 根据时间戳实现自动无重复字符串定义// 获取UUIDpublic static UUID randomUUID()
- 后台Java代码【验证码生成】/** * 随机生成6位随机验证码 */ public static String createRandomV
- 浅谈java内存模型 不同的平台,内存模型是不一样的,但是jvm的
- Android 遍历SDCARD的文件夹并显示目录信息private String mResult = new String(); priv
- 日期格式处理在控制器中使用对象接收数据前端:<form action="test/add" method=&quo
- java输入流报错:Exception in thread "main" java.util.NoSuchElement
- 在项目中,有时候会用到领域枚举和DTO枚举的映射和转换。有一个现实的问题是:如果领域枚举项发生变化,而DTO枚举项没有及时更新,这样会造成映
- * 验证码地址:https://007.qq.com/online.html* 使用OpenCv模板匹配* 成功率90%左右* Java +
- 在程序中,进行类型转换是常见的事,C#支持基本的强制类型转换方法,例如:Object obj1 = new NewType();NewTyp
- Android ScrollView无法填充满屏幕的解决办法ScrollView滚动视图是指当拥有很多内容、屏幕显示不完时、需要通过滚动跳来
- 如果不熟悉Java8新特性的小伙伴,初次看到函数式接口写出的代码可能会是一种懵逼的状态,我是谁,我在哪,我可能学了假的Java,(・∀・(・
- Java 的表格表格是一个由多行,多列组成的二维显示区。Swing的JTable以及相关类提供了对这种表格的支持,程序既可以使用简单的代码创
- 产生90-100的重复的随机数:public class RandomTest { public static void main(Str