注册 登录

清河洛

fyne中的容器和布局

qingheluo2024-08-13清河洛612
fyne中的画布对象需要使用Window.SetContent(CanvasObject)方法放置在窗口中才能在界面显示多次使用会设置最后一个画布对象到窗口中,也就是说一个Window仅能容纳一个CanvasObject当需要多个CanvasObject放置在同一个Window中时,我们使用容器容器是一种特殊的CanvasObject,里面放置的是若干个子CanvasObject也就是说容器将多个CanvasObject打包为一个CanvasObject,并且其中的每个元素按照规定的规则有序的排列在fyne中一个容器中的元素布局规则,我们称之为Layout(布局)容器可以嵌套使用,用来实...

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()


网址导航