View Margins And Paddings
Each view can have margins and paddings. They help manage spaces between views and inside their content, which makes layouts look neat and visually appealing. To have a better understanding lets describe them visually.
Margin determines the outer indent from the view to its neighbors. While the padding sets the padding from the border of the view to its content. View can't have children by itself therefore these attributes play a big role when we start using a container views.
Below is the list of properties responsible for adjusting margin and padding values.
Property | Description |
---|---|
"margin" | Describe all margins |
"padding" | Describe all paddings |
"margin-left" | Left margin |
"margin-right" | Right margin |
"margin-top" | Top margin |
"margin-bottom" | Bottom margin |
"padding-left" | Left padding |
"padding-right" | Right padding |
"padding-top" | Top padding |
"padding-bottom" | Bottom padding |
The main properties are "margin" and "padding."
Other properties adjust the values of these two.
We can specify one or multiple values for these properties to set all margins and paddings at once.
When using a single value, it will apply to all sides of the view, typically the value has SizeUnit
type:
Examples
Setting all margins and paddings to the same value from code.
Go
// Setting margins
view.Set(rui.Margin, rui.Px(8))
// Setting paddings
view.Set(rui.Padding, rui.Px(4))
Setting margins and paddings in the view description file.
RUI
ListLayout {
content = [
TextView {
text = "Item 1",
margin = 8px,
padding = 4px,
},
TextView {
text = "Item 2",
margin = 8px,
padding = 4px,
},
],
}
Another way of setting margins and paddings is to provide multiple values for these properties.
In this case properties will hold the value of BoundsProperty
interface.
To create such interface we use rui.NewBoundsProperty()
or rui.NewBounds()
global functions.
The interface holds four properties of SizeUnit
type:
Property | Description |
---|---|
"left" | Left value |
"right" | Right value |
"top" | Top value |
"bottom" | Bottom value |
Example
Setting margins and paddings from code.
Go
view.Set(rui.Margin, rui.NewBoundsProperty(rui.Params {
rui.Left: "@leftMargin", // Setting the value by referring to the constant
rui.Right: "1.5em", // Setting the value as a text representation of SizeUnit type
rui.Top: rui.Px(8), // Setting the value in pixels using SizeUnit type
rui.Bottom: rui.Inch(0.3), // Setting the value in inches using SizeUnit type
}))
view.Set(rui.Padding, rui.NewBoundsProperty(rui.Params {
rui.Left: "@leftPadding", // Setting the value by referring to the constant
rui.Right: "0.5em", // Setting the value as a text representation of SizeUnit type
rui.Top: rui.Px(4), // Setting the value in pixels using SizeUnit type
rui.Bottom: rui.Inch(0.1), // Setting the value in inches using SizeUnit type
}))
view.Set(rui.Margin, rui.NewBounds(
rui.Px(8), // Top margin, setting the value in pixels using SizeUnit type
rui.Em(1.5), // Right margin, setting the value Em using SizeUnit type
rui.Inch(0.3), // Bottom margin, setting the value in inches using SizeUnit type
10, // Left margin, setting the value in pixels using int type
))
view.Set(rui.Padding, rui.NewBounds(
rui.Px(8), // Top padding, setting the value in pixels using SizeUnit type
rui.Em(1.5), // Right padding, setting the value Em using SizeUnit type
rui.Inch(0.3), // Bottom padding, setting the value in inches using SizeUnit type
10, // Left padding, setting the value in pixels using int type
))
The BoundsProperty
interface has its own text representation, which can be used when describing the view from a resource file, it has the following format:
RUI
_{
left = <value>,
right = <value>,
top = <value>,
bottom = <value>,
}
where <value>
could be a text representation of SizeUnit
type or a reference to a constant.
Example
Setting margins and paddings from view description file.
RUI
ListLayout {
content = [
TextView {
text = "Item",
margin = _{
top = 8px, // Setting value in pixels
left = @leftMargin, // Referring to a constant
right = 1.5em, // Setting value in em
bottom = 0.3in, // Setting value in inches
},
padding = _{
top = 4px, // Setting value in pixels
left = @leftPadding, // Referring to a constant
right = 0.5em, // Setting value in em
bottom = 0.1in, // Setting value in inches
},
},
],
}
A convenient way of getting "margin" an "padding" properties value is to use a dedicated global functions GetMargin()
and GetPadding()
:
Go
marginBounds := rui.GetMargin(rootView, viewId)
paddingBounds := rui.GetPadding(rootView, viewId)
The values will be returned in a form of the Bounds
structure:
Go
type Bounds struct {
Top, Right, Bottom, Left SizeUnit
}
We can also use a well known Get()
method of the view but remember that we have to perform a type conversion and resolve constants manually in this case.
To grab the values from BoundsProperty
we can use its Bounds()
method:
Go
if value := view.Get(rui.Margin); value != nil {
margin := value.(BoundsProperty)
values := margin.Bounds()
// Do something with the values
}
if value := view.Get(rui.Padding); value != nil {
padding := value.(BoundsProperty)
values := padding.Bounds()
// Do something with the values
}
Properties beginning with "margin-" or "padding-" have a SizeUnit
type and can also accept constants or text representations of the SizeUnit
type.
When setting such properties library will first check for existence of "margin" or "padding" properties, create them when needed and update their values based on supplied values in "margin-..." or "padding-..." properties.
Examples
Setting margins and paddings in the view description file.
RUI
ListLayout {
content = [
TextView {
text = "Item 1",
margin-left = 8px,
margin-right = 8px,
padding-top = 4px,
padding-bottom = 4px,
},
TextView {
text = "Item 2",
margin-left = 8px,
margin-right = 8px,
padding-top = 4px,
padding-bottom = 4px,
},
],
}
Setting margins and paddings from code.
Go
// Setting margins
view.Set(rui.MarginLeft, rui.Px(8))
view.Set(rui.MarginRight, rui.Px(12))
// Setting paddings
view.Set(rui.PaddingTop, rui.Px(4))
view.Set(rui.PaddingBottom, rui.Px(4))
Margins are not part of the view shape, which is defined by the "width" or "height" properties. To illustrate this, let's assume that we want to place a view inside a container and create some space between the container's border and the child view. We can achieve this by setting the "margin" property of the child view and specifying its "width" and "height" as 100%:
RUI
GridLayout {
width= 300px,
height = 200px,
content = EditView {
edit-view-type = multiline,
// Setting child dimensions
width = 100%,
height = 100%,
margin = 1em, // Setting child margin
}
}
Since margin does not affect the border or shape of the view we'll have something similar to this:
Notice that the child view has the same width and height as a parent container but exceeds the parent's dimensions because of the margins. To overcome this issue, we have to somehow specify correct dimensions for the child view that include its margin. The right way to do this is to utilize a function that subtracts margins from these 100% values of the container's width or height:
RUI
GridLayout {
width= 300px,
height = 200px,
content = EditView {
width = "sub(100%, 2em)", // Subtracting two margins from the parent's width
height = "sub(100%, 2em)", // Subtracting two margins from the parent's height
edit-view-type = multiline,
margin = 1em, // Setting margin
}
}
This will fit our child view inside the container nicely without any overflow.
We can use functions like sub()
and others to specify property value from the source code as well.
Go
view := rui.NewGridLayout(session, rui.Params{
rui.Width: rui.Px(300),
rui.Height: rui.Px(200),
rui.Content: rui.NewEditView(session, rui.Params{
rui.EditViewType: rui.MultiLineText,
rui.Width: rui.SubSize(rui.Percent(100), rui.Em(2)), // Subtracting two margins from the parent's width
rui.Height: rui.SubSize(rui.Percent(100), rui.Em(2)), // Subtracting two margins from the parent's height
rui.Margin: rui.Em(1), // Setting margin
}),
})
For more information on how to use such functions please refer to SizeUnit
and SizeFunc
reference documentation.
There is also another way to achieve the same result: we can set paddings in the parent container, as padding participates in the width or height calculations of the child view:
RUI
GridLayout {
width= 300px,
height = 200px,
padding = 1em,
content = EditView {
width = 100%, // Width of the parent's content area(excluding paddings)
height = 100%, // Height of the parent's content area(excluding paddings)
edit-view-type = multiline,
}
}