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
0
投稿
猜你喜欢
- 我们在代码中经常使用using保障非托管资源的释放 static void Main(string[] args){
- 关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种:第一种:通过注解@PostConstruct 和 @
- 刚刚开始学习C#,想自己做一个网页游戏的挂。游戏里面有收钱的动作,一个建筑物一个建筑物的点,很累啊。于是想用C#模拟鼠标操作替我收钱,想着学
- 一、Unity Shader基础1、创建和使用Shader在Unity中Shader一般由两种用途:指定给材质,用于物理渲染;指定给脚本,用
- 这篇文章主要介绍了spring cloud gateway请求跨域问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定
- 我们玩玩手机的录像功能吧。做个DEMO。 看看录制过程: mediarecorder = new MediaRecorder();// 创建
- 实现效果:奔溃的线程侠:(单线程)主线程正在处理刷新图片的请求时,无法再接受其他请求,从而陷入阻塞的死循环状态。绘制图片import jav
- JAVA中的类只能是public 或者package的。这是符合逻辑的:人们定义类的初衷就是为了让别人用的。倘若是private,别人怎么调
- 在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的类和这个类的方法可以使用,其他的类都无法访问到这个private
- 前言在讲述线程池的前提 先补充一下连接池的定义连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用可以看到其连接
- Android Support Annotations &
- 如下所示:<span style="font-size:14px;">package com.imooc.r
- 1. 概述官方JavaDocsApi: java.awt.Component,java.awt.Containernull,绝对布局。绝对布
- 日常对于金额计算,应该都是用的BigDecimal,可是苦于没有好的工具类方法,现在贡献一个我正在用的对于数字计算的工具类,项目中就是用的这
- 问题是这样的在开发时,为了节约时间,我选择了mybatis框架来开发,然后又在网上找了一个许多人都推荐的mybatis-plus来作为持久层
- WPF 窗体设置亚克力效果框架使用大于等于.NET40。Visual Studio 2022。项目使用 MIT 开源许可
- 前言这几天看《Java并发编程之美》的时候又遇到了ThradLocal这个类,不得不说,这个类在平时很多场景都遇得到,所以对其进行一个系统性
- 重新认识 Java 的 System.in以前也写过不少命令行的程序,处理文件时总需要通过参数指定路径,直到今天看资料时发现了一种我自己从来
- 本人新手,有什么问题 还请指出来,大家一起学习进步,话不多说。首先,搭建dubbo项目,要有三个工程。它们分别是:maven java工程
- 说明:在阅读本篇文章之前建议大家先详细学习一下spring的相关知识,有助于更深刻的理解spirngboot的配置原理。一、什么是sprin