最后
目前已经更新的部分资料:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
-
Flutter如何实现控件布局达到3D效果?
-
Flutter如何实现子控件旋转、自动旋转、手势滑动时关联子控件旋转滚动?快速滑动抬手继续旋转滚动?
-
Flutter如何实现多个布局叠加时前面遮挡后面?
1.子布局按照圆形顺序放置且平分角度
如上图所示:
如上图所示(参考系:最下方为0度,逆时针旋转角度增加
)
第一个点
解:根据已知条件列方程式
x2=width/2+sin(a)*R
y2=height/2+cos(a)*R
第二个点
解:根据已知条件列方程式①
① x=width/2-sin(b)*R
y=height/2-cos(b)*R
因为b=a-180,所以带入①方程得:
② x=width/2-sin(a-180)*R
y=height/2-cos(a-180)*R
又因为sin(k*360+a)=sin(a),所以②方式可以修改为:
③ x=width/2-sin(180+a)*R
y=height/2-cos(180+a)*R
又又因为 sin(180+a)=-sin(a),cos(180+a)=-cosa 带入③方程式得:
④ x=width/2+sin(a)*R
y=height/2+cos(a)*R
由上面2点计算得,每个子布局的中心点坐标公式统一为:
x=width/2+sin(a)*R
y=height/2+cos(a)*R
以上所用三角函数公式表:
通过上面计算得出子控件的位置公式后,开始我们的代码。
实现子控件按照圆形布局及平分角度代码如下:
//所有子控件的位置数据
//count:子控件数量;
//startAngle:开始角度默认为0;
//rotateAngle:偏转角度默认为0;
List _childPointList({Size size = Size.zero}) {
List childPointList = [];
double averageAngle = 360 / count;
double radius = size.width / 2 - childWidth / 2;
for (int i = 0; i < count; i++) {
/***子布局角度/
double angle = startAngle + averageAngle * i + rotateAngle;
//子布局中心点坐标
var centerX = size.width / 2 + sin(radian(angle)) * radius;
var centerY = size.height / 2 + cos(radian(angle)) * radius;
childPointList.add(Point(
centerX,
centerY,
childWidth,
childHeight,
centerX - childWidth / 2,
centerY - childHeight / 2,
centerX + childWidth / 2,
centerY + childHeight / 2,
1,
angle,
i,
));
}
return childPointList;
}
///角度转弧度
///弧度 =度数 * (π / 180)
///度数 =弧度 * (180 / π)
double radian(double angle) {
return angle * pi / 180;
}
2.子布局如何旋转?自动旋转?支持手势滑动旋转?快速滑动抬手继续旋转?
子布局如何旋转
所谓的旋转就是所有的子布局绕着圆形移动,布局一旦移动就代表中间位置改变,根据上面我们计算的子布局位置的公式来看:
中心点坐标
x=width/2+sin(a)*R
y=height/2+cos(a)*R
因为width
和R
都是已知并且定下来的尺寸,所以说,想要改变中心点坐标,只需修改 角度a就可以了。要想达到旋转效果的话就是让所有的子布局都同时移动相同的角度即可。
子布局原始角度值:
double angle = startAngle + averageAngle * i;
我们可以在此基础上加上一个可变的角度值,通过改变这个值,所有的子布局都会同时加上此值同时移动了位置。如下:
double angle = startAngle + averageAngle * i + rotateAngle;
其中 rotateAngle 就是可变的值。改变这个值就能让布局动起来
自动旋转
同理,我们只要搞个定时器,周期性修改这个rotateAngle
值,并setState(() {})
刷新下,看起来就自动旋转了。
支持手势滑动旋转
大家已经知道通过修改rotateAngle
值去实现旋转,那么支持手势滑动旋转顾名思义就是通过手势修改这个rotateAngle值就OK,那么手势处理Flutter提供了GestureDetector
组件,这个组件功能很强大,这里面我们使用了他的几个回调方法。
本次实现直接使用水平滑动监听,大家如果想兼容竖直滑动可以自己尝试修改就可以。
GestureDetector(
///水平滑动按下
onHorizontalDragDown: (DragDownDetails details) {…},
///水平滑动开始
onHorizontalDragStart: (DragStartDetails details) {
//记录拖动开始时当前的选择角度值
downAngle = rotateAngle;
//记录拖动开始时的x坐标
downX = details.globalPosition.dx;
},
///水平滑动中
onHorizontalDragUpdate: (DragUpdateDetails details) {
//滑动中X坐标值
var updateX = details.globalPosition.dx;
//计算当前旋转角度值并刷新
rotateAngle = (downX - updateX) * slipRatio + downAngle;
if (mounted) setState(() {});
},
///水平滑动结束
onHorizontalDragEnd: (DragEndDetails details) {…},
///滑动取消
onHorizontalDragCancel: () {…},
behavior: HitTestBehavior.opaque,//deferToChild translucent
child: xxx,
);
快速滑动抬手继续旋转
抬手还能继续旋转,也就是当我们快速滑动抬手的时候只要继续修改旋转角度值rotateAngle
就可以达到继续旋转的效果。当我们抬手的时候我们可以拿到什么呢?
例如:当我们骑着小黄单车在大路上快速的蹬着脚蹬子然后停止蹬,你的小黄已当时的速度飞驰在这个大路上,由于地面的摩擦力的影响,速度会越来越小,最后停止。
///水平滑动结束
onHorizontalDragEnd: (DragEndDetails details) {
//x方向上每秒速度的像素数
velocityX = details.velocity.pixelsPerSecond.dx;
_controller.reset();
_controller.forward();
},
//动画设置rotateAngle
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1000),
);
animation = CurvedAnimation(
parent: _controller,
curve: Curves.linearToEaseOut,
);
animation = new Tween(begin: 1, end: 0).animate(animation)
…addListener(() {
//当前速度
var velocity = animation.value * -velocityX;
var offsetX = radius != 0 ? velocity * 5 / (2 * pi * radius) : velocity;
rotateAngle += offsetX;
setState(() => {});
})
…addStatusListener((status) {
if (status == AnimationStatus.completed) {
rotateAngle = rotateAngle % 360;
_startRotateTimer();
}
最后
由于题目很多整理答案的工作量太大,所以仅限于提供知识点,详细的很多问题和参考答案我都整理成了 PDF文件
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
题目很多整理答案的工作量太大,所以仅限于提供知识点,详细的很多问题和参考答案我都整理成了 PDF文件
[外链图片转存中…(img-AQ0uTC8l-1715719533699)]
[外链图片转存中…(img-a774dHcP-1715719533700)]
[外链图片转存中…(img-kG0rZGUn-1715719533700)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!