绑定自定义布局
在Fyne应用程序中,每个Container使用简单的布局算法排列其子元素。Fyne定义了Fyne.io/Fyne/v2/layout包中可用的许多布局。如果您查看代码,就会发现它们都实现了Layout接口。
go
type Layout interface {
Layout([]CanvasObject, Size)
MinSize(objects []CanvasObject) Size
}
任何应用程序都可以提供自定义布局,以非标准方式排列小部件。为此,您需要在自己的代码中实现上面的接口。为了说明这一点,我们将创建一个新布局,该布局以对角线排列元素,并将其排列在容器的左下方
首先,我们将定义一个新的类型,对角线,并定义它的最小大小。为了计算它,我们只需将所有子元素的宽度和高度(指定为[]fyne.CanvasObject参数)添加到MinSize。
go
import "fyne.io/fyne/v2"
type diagonal struct {
}
func (d *diagonal) 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()函数,该函数应将所有指定对象移动到第二个参数中指定的fyne.Size中。
在我们的实现中,我们计算小部件的左上角(这是0 x参数,具有y位置,即容器的高度减去所有子项高度的总和)。从顶部位置开始,我们只需将每个项目的位置前移上一个子项目的大小。
go
func (d *diagonal) Layout(objects []fyne.CanvasObject, containerSize fyne.Size) {
pos := fyne.NewPos(0, containerSize.Height - d.MinSize(objects).Height)
for _, o := range objects {
size := o.MinSize()
o.Resize(size)
o.Move(pos)
pos = pos.Add(fyne.NewPos(size.Width, size.Height))
}
}
这就是创建自定义布局的全部内容。现在代码已经全部编写完毕,我们可以将其用作container.New的布局参数。下面的代码设置了3个Label小部件,并将它们放置在具有新布局的容器中。如果您运行此应用程序,您将看到对角小部件排列,并且在调整窗口大小时,它们将与可用空间的左下角对齐。
go
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
)
func main() {
a := app.New()
w := a.NewWindow("Diagonal")
text1 := widget.NewLabel("topleft")
text2 := widget.NewLabel("Middle Label")
text3 := widget.NewLabel("bottomright")
w.SetContent(container.New(&diagonal{}, text1, text2, text3))
w.ShowAndRun()
}