I decided to try out flutter and implement one of my favorite projects for a UI Toolkit, “The Circle.” It starts with just drawing a circle on the screen and then changing its color on tap, there are more steps, each one adding complexity but I’ll focus on these two for now to discuss something interesting.
我决定尝试抖动,并为UI工具包“ The Circle”实现我最喜欢的项目之一。 首先从在屏幕上绘制一个圆圈,然后在点击时更改其颜色开始,还有更多步骤,每个步骤都会增加复杂性,但现在我将重点讨论这两个,以讨论一些有趣的事情。
If I were doing something similar on Android, I’d just draw a circle on the canvas in a CustomView. Being an amateur in flutter, I looked up for an equivalent API in flutter, and there is one, the CustomPainter.
如果我在Android上执行类似的操作,则只需在CustomView的画布上绘制一个圆圈。 作为业余爱好者,我寻找了一个等效的API,其中有一个CustomPainter 。
Let’s look into some things which I found are easy to miss but very important to be aware of.
让我们研究一些我发现容易错过但很重要的事情。
1.视界 (1. The View Bounds)
So I created DrawCircle
which extends CustomPainter and can draw a circle on the canvas.
因此,我创建了DrawCircle
,它扩展了CustomPainter并可以在画布上绘制一个圆。
Then I created a custom widget Circle
and internally it returned a CustomPaint
object.
然后,我创建了一个自定义小部件Circle
并在内部返回了CustomPaint
对象。
This code is just a snippet, you can check out the full code in the repository linked at the end. And it worked!
这段代码只是片段,您可以在最后链接的存储库中查看完整的代码 。 而且有效!
Then onto the next job, changing the color on click, again, a quick google search led me to the GestureDetector, and given flutter’s compositive nature, it was reasonably easy to implement it.
然后,在接下来的工作,改变对点击的颜色,同样,一个快速谷歌搜索导致我GestureDetector ,并给予扑的综合性质,它是相当容易实现它。
Based on the code written, the method onCircleTapped
should be triggered when I tapped the circle … but it is not 😟
根据编写的代码,当我轻按圆圈时应触发onCircleTapped
方法……但不是😟
So I looked at flutter inspector, and this is what I found. The Circle
widget has zero height and width … and thus no bounds.
所以我看着颤振检查器 ,这就是我发现的。 Circle
小部件的高度和宽度为零,因此没有界限。
This is the first takeaway,
这是第一个外卖,
While using CustomPainter, make sure you give it the correct size so that it can give create bounds for the view. This directly affects interactions with user and other views in the layout.
使用CustomPainter时,请确保为其提供正确的大小,以便可以为视图提供创建边界。 这直接影响与用户和布局中其他视图的交互。
So I modified the CustomPaint
with a size and guess what, the bounds showed up, and clicks started working.
所以我修改了CustomPaint
的大小,然后猜测是什么,边界出现了,点击开始起作用。
2.加强界限 (2. Enforcing the bounds)
But there’s one more thing, what if I give it particular size, but try to paint something which will take more area than what I defined 🤔.
但是还有另外一件事,如果我给它特定的大小,该怎么办,但要尝试画比我定义的要占更多面积的东西🤔。
And there’s another problem. The drawing can go beyond the bounds, which can be an issue where multiple widgets on a screen maintained by a team. A widget should only be able to work within the bounds it is given and not affect what’s outside in any way. Also, you can see that the circle is not centered because alignment works based on the actual bounds, which are centered 🤷🏻♂️.
还有另一个问题。 绘图可能会超出范围,这可能是团队在屏幕上维护多个小部件的问题。 小部件只能在给定的范围内工作,而不能以任何方式影响外部事物。 此外,您可以看到圆没有居中,因为对齐是基于实际边界(居中🤷🏻♂️)进行的。
The second takeaway,
第二点,
Wrap your CustomPaint in a `ClipRect` widget. What this will do is prevent the drawing from flowing out of the its bounds.
将您的CustomPaint包装在` ClipRect`小部件中。 这将防止图形从其边界流出。
Here’s the change I had to make in Circle
这是我必须在Circle
进行的更改
And voila! CustomPainter
can only draw inside the bounds now. Even if it tried to cross them, it’d be clipped. This will make sure that even if you make a mistake in the calculation while drawing, this widget might look messed up, but it won’t affect other widgets on the screen.
瞧! CustomPainter
现在只能在边界内绘制。 即使它试图越过它们,它也会被剪掉。 这样可以确保即使您在绘制时在计算中犯了错误,该小部件也可能看起来很混乱,但不会影响屏幕上的其他小部件。
So, those were the two things you should take care of while using CustomPaint in flutter. In the final version, I ended up using ClipOval, better suited for the circle use-case and fixed the circle dimensions. You can check out the full code in this repository.
所以 ,这是在Flutter中使用CustomPaint时应注意的两件事。 在最终版本中,我最终使用了更适合圆形用例的ClipOval并修复了圆形尺寸。 您可以在 此存储库中 检出完整的代码 。
Also, this was my first time writing about flutter, and I definitely plan to experiment more and share it with everyone.
另外,这是我第一次写关于颤动的文章,我当然计划进行更多的实验并与大家分享。
Until the next one, Stay safe and stay indoors. Ciao!
直到下一个,保持安全并留在室内。 再见!