fyne中的容器和布局
fyne中的画布对象需要使用Window.SetContent(CanvasObject)方法放置在窗口中才能在界面显示
多次使用会设置最后一个画布对象到窗口中,也就是说一个Window仅能容纳一个CanvasObject
当需要多个CanvasObject放置在同一个Window中时,我们使用容器
容器是一种特殊的CanvasObject,里面放置的是若干个子CanvasObject
也就是说容器将多个CanvasObject打包为一个CanvasObject,并且其中的每个元素按照规定的规则有序的排列
在fyne中一个容器中的元素布局规则,我们称之为Layout(布局)
容器可以嵌套使用,用来实现复杂的界面显示内容
在fyne主包中对容器的定义
type Container struct { Hidden bool Layout Layout Objects []CanvasObject } 容器包含若干CanvasObject元素的,并且所有元素按照Layout指定的布局方式进行布局显示
容器的创建
NewContainerWithoutLayout(objects ...CanvasObject) *Container 不使用布局创建容器 NewContainer(objects ...CanvasObject) *Container 上面函数的别名,内部调用了上面的函数 NewContainerWithLayout(layout Layout, objects ...CanvasObject) *Container 使用指定布局创建容器 在"fyne/container"包中,也定义了两个函数 container.NewWithoutLayout(objects ...fyne.CanvasObject) *fyne.Container container.New(layout fyne.Layout, objects ...fyne.CanvasObject) *fyne.Container
容器的常用方法
容器是特殊CanvasObject,所以CanvasObject可以用的方法容器也可以使用
另外容器拓展了一些专有的方法
Add(add CanvasObject) // 添加一个新的元素到容器中 AddObject(o CanvasObject) // Add()的别名,内部调用Add() Remove(rem CanvasObject) RemoveAll()
选项卡
选项卡是在开发中经常用到的,在"fyne/container"包中定义了AppTabs用于表示选项卡容器
type AppTabs struct { Items []*TabItem OnSelected func(*TabItem) OnUnselected func(*TabItem) }
其中TabItem表示选项卡的元素成员
type TabItem struct { Text string Icon fyne.Resource Content fyne.CanvasObject } container.NewTabItem(text string, content fyne.CanvasObject) *TabItem container.NewTabItemWithIcon(text string, icon fyne.Resource, content fyne.CanvasObject) *TabItem
创建选项卡
container.NewAppTabs(items ...*TabItem) *AppTabs
选项卡容器的常用方法
SetTabLocation(l TabLocation) 设置选项卡选项的位置 type TabLocation int // 表示不同的位置 const ( TabLocationTop TabLocation = iota TabLocationLeading TabLocationBottom TabLocationTrailing ) Append(item *TabItem) SetItems(items []*TabItem) DisableIndex(i int) DisableItem(item *TabItem) // 禁用某个元素 EnableIndex(i int) EnableItem(item *TabItem) SelectIndex(index int) Select(item *TabItem) Selected() *TabItem SelectedIndex() int
在fyne主包中对布局进行了定义,在"fyne/layout"包中实现了一些常见的布局
一、盒子(box)
盒子布局有两种方式
1、layout.NewHBoxLayout() 水平 将所有元素排列在单行 每个元素宽度均设置为最小值,高度均相等,是所有元素高的最大值 NewCustomPaddedHBoxLayout(padding float32) fyne.Layout 创建使用指定内边距的水平布局 2、layout.NewVBoxLayout() 垂直 将所有元素排列在单列 每个元素高度均设置为最小值,宽度均相等,是所有元素宽的最大值 layout.NewSpacer()方法用于创建分隔符(空白元素) 将自动拓展宽和高以填充所有可用空间 在水平布局开头添加一个将导致所有元素右对齐 在水平布局开头和结尾各添加一个,所有元素居中对齐 垂直布局中使用方式相似
网格(grid)
以具有固定列或列数的网格模式布置元素
元素将填充一行或一列,直到满足指定数,之后将创建一个新行或列
layout.NewGridLayoutWithColumns(cols int) 创建固定列数的网格布局 layout.NewGridLayout(cols) 上面函数的别名 layout.NewGridLayoutWithRows(rows int) 创建固定行数的网格布局
网格环绕(grid wrap)
网格包裹布局中每个元素具有相同的宽和高,元素优先填充行,当前行剩余空间不足时创建一个新行
layout.NewGridWrapLayout(size fyne.Size) fyne.Layout
注意:网格环绕布局在初始化时为一列,只有当调整窗口大小时才重新排列子元素
边框(border)
设置上、下、左、右四个元素,其余元素都将被定为到中心区域并自动拓展以填充可用区域
就好像使用元素作为边框,可以传递nil作为边框
layout.NewBorderLayout(top, bottom, left, right fyne.CanvasObject) fyne.Layout
表单(form)
类似于固定2列的网格布局
第一列宽度自动设置为所有第一列元素宽度中的最大值
第二列宽度自动扩充以填充剩余空间
layout.NewFormLayout() fyne.Layout
居中(center)
将所有元素在可用空间的中心堆叠放置,后面的元素会覆盖在之前元素上面
layout.NewCenterLayout() fyne.Layout
其他布局
layout.NewPaddedLayout() fyne.Layout // 使用当前theme的padding layout.NewCustomPaddedLayout(padTop, padBottom, padLeft, padRight float32) fyne.Layout layout.NewStackLayout() fyne.Layout
最大化(max)
将所有元素设置为与容器相同的大小,容器的尺寸为所有元素中的最大元素的最小尺寸
后面的元素会覆盖在之前元素上面
layout.NewMaxLayout() fyne.Layout
为了方便开发,在"fyne/container"包中定义了一些常用的布局容器
其本质就是在方法内部先创建对应布局,在创建容器应用,最后返回
NewHBox(objects ...fyne.CanvasObject) *fyne.Container layout.NewHBoxLayout() NewVBox(objects ...fyne.CanvasObject) *fyne.Container layout.NewVBoxLayout() NewGridWithColumns(cols int, objects ...fyne.CanvasObject) *fyne.Container layout.NewGridLayoutWithColumns(cols) NewGridWithRows(rows int, objects ...fyne.CanvasObject) *fyne.Container layout.NewGridLayoutWithRows(rows) NewGridWrap(size fyne.Size, objects ...fyne.CanvasObject) *fyne.Container layout.NewGridWrapLayout(size) container.NewBorder(top, bottom, left, right fyne.CanvasObject, objects ...fyne.CanvasObject) *fyne.Container layout.NewBorderLayout(...) NewCenter(objects ...fyne.CanvasObject) *fyne.Container layout.NewCenterLayout() NewPadded(objects ...fyne.CanvasObject) *fyne.Container layout.NewPaddedLayout() NewStack(objects ...fyne.CanvasObject) *fyne.Container layout.NewStackLayout()