秋来冬风的博客

自定义布局,Fyne笔记第6篇

目录

这是我的Fyne学习笔记系列第6篇。

Fyne自带的容器已经提供了不少的布局。但在实际开发中,还是存在需要其他布局的场景。

Fyne的布局是一个接口

type Layout interface {
	Layout([]CanvasObject, Size)
	MinSize(objects []CanvasObject) Size
}

意味着可以自定义实现。

其中MinSize一般只要把每个小部件的大小加起来即可。

例如

type common struct{}

func (common) MinSize(objects []fyne.CanvasObject) fyne.Size {
	w, h := float32(0), float32(0)
	for _, o := range objects {
		childSize := o.MinSize()

		w += childSize.Width
		h += childSize.Height
	}
	return fyne.NewSize(w, h)
}

关键在于Layout方法,这里通过对小部件在一个限定的容器大小内进行移动和改变大小来实现特定布局。

对于高度,0对应容器顶部,越大里容器顶部越远。

对于宽度,0对应容器最左边,越大离容器最左边越远。

以实现按0.1,0.8,0.1的比例占据屏幕高度排列为例子,即常见的Head,Body,Footer布局App

type DemoLayout struct{}

func (d *Demo) Layout(objects []fyne.CanvasObject, containerSize fyne.Size) {
	if len(objects) == 3 {
		panic("should 3")
	}

	ratios := []float32{0.1, 0.8, 0.1}
	heights := make([]float32, len(ratios))
	for i, ratio := range ratios {
		heights[i] = containerSize.Height * ratio
	}

	currentY := float32(0)
	for i, obj := range objects {
		// 设置小部件大小:宽度占满容器,高度按比例
		obj.Resize(fyne.NewSize(size.Width, heights[i]))
		// 设置小部件位置:X=0(左对齐),Y=当前偏移量
		obj.Move(fyne.NewPos(0, currentY))
		// 更新 Y 轴偏移量
		currentY += heights[i]
	}
}

Layout方法仅包含简单一些代码,但实现了想要的布局。

fyne/container包的函数

func New(layout fyne.Layout, objects ...fyne.CanvasObject) *fyne.Containe

让我们可以使用自定义布局来创建容器。

Tags:
Categories: