如果多個控件都放在頁面上,OpenUI5 會怎么安排控件的位置呢?如何按自己的想法安排控件的位置呢?Layout 控件就是專門來對控件的位置進行管理的。本篇介紹表格型布局 ( grid layout)。
Grid Layout 控件簡介
Grid Layout 控件負責將頁面進行表格式布局,頁面被分為 12 列,子控件從左至右排列。每個控件并不是占一列,OpenUI5 根據屏幕的大小,將屏幕分為 4 種,分別是 特大 ( XL: extra large )、大 ( L: large )、中等 ( M: medium ) 和 小 ( S: small )。特大的比如 PC 機的大桌面,大的比如 PC 的桌面,中等的比如平板,小的比如手機。默認情況下,每個控件在 XL 桌面上占 3 列,在 L 桌面上占 3 列,在 M 桌面上占 6 列,在
S 桌面上占 12 列。OpenUI5 用一個字符串表示為 XL3 L3 M6 S12
,通過 defaultSpan
屬性來設置。
當屏幕的尺寸變更的時候,OpenUI5 檢測到尺寸的變化,根據上面的 4 個分類對控件的位置進行調整,從而實現所謂的 自適應。
Grid layout 控件寬度 (width 屬性),可以基于像素,或者基于頁面寬度的相對比例。控件之間的間距可以通過 vSpacing
和 hSpacing
屬性進行設置。
沒有布局的控件位置是如何安排的?
假設我們現在編寫一個含有選擇問答題的頁面。每一個問題提供 A、B 兩種答案。示例的問答包括兩個問題:
- 頁面上有兩個 Logo,哪一個更好?
- 是否否喜歡 JavaScript 語言?
頁面用 OpenUI5 控件實現,代碼都寫在 index.html 中,源碼如下:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<!-- Bootstrap -->
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal">
</script>
<!-- Application area -->
<script>
function initialization() {
// 兩個image為兩個logo
var oImage1 = new sap.m.Image({
src: "img/alice.png",
decorative: false,
alt: 'Alice'
});
var oImage2 = new sap.m.Image({
src: "img/Hellen.png",
decorative: false,
alt: 'Helen'
});
// 詢問更喜歡哪一個logo
var oLabel1 = new sap.m.Label("label1", {
text: "Which logo do you like better?"
});
// 答案放在radioButton中
var oRadioBtnGrp1 = new sap.m.RadioButtonGroup({
columns: 2,
ariaLabelledBy: oLabel1,
buttons: [
new sap.m.RadioButton({ text: "Left logo" }),
new sap.m.RadioButton({ text: "Right logo"}),
]
});
// 詢問是否喜歡javascript
var oLabel2 = new sap.m.Label({
text: "Do you like JavaScript?"});
// 答案放在radioButton中
var oRadioBtnGrp2 = new sap.m.RadioButtonGroup({
columns: 2,
ariaLabelledBy: oLabel2,
buttons: [
new sap.m.RadioButton({text: "Yes"}),
new sap.m.RadioButton({text: "No" }),
]
});
oImage1.placeAt("content");
oImage2.placeAt("content");
oLabel1.placeAt("content");
oRadioBtnGrp1.placeAt("content");
oLabel2.placeAt("content");
oRadioBtnGrp2.placeAt("content");
};
sap.ui.getCore().attachInit(initialization);
</script>
</head>
<!-- UI area -->
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
運行一下,我們得到的頁面如下圖所示:
兩個問題都在同一行中,顯得比較亂。
Grid Layout (表格式布局)
OpenUI5 是從左到右依次對控件進行放置的。我們需要添加布局控件對這些控件位置進行管理管理。先將代碼修改如下:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<!-- Bootstrap -->
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m, sap.ui.layout"
data-sap-ui-theme="sap_bluecrystal">
</script>
<!-- Application area -->
<script>
function initialization() {
// 兩個image為兩個logo
var oImage1 = new sap.m.Image({
src: "img/alice.png",
decorative: false,
alt: 'Alice'
});
var oImage2 = new sap.m.Image({
src: "img/Hellen.png",
decorative: false,
alt: 'Helen'
});
// 詢問更喜歡哪一個logo
var oLabel1 = new sap.m.Label("label1", {
text: "Which logo do you like better?"
});
// 答案放在radioButton中
var oRadioBtnGrp1 = new sap.m.RadioButtonGroup({
columns: 2,
ariaLabelledBy: oLabel1,
buttons: [
new sap.m.RadioButton({ text: "Left logo" }),
new sap.m.RadioButton({ text: "Right logo"}),
]
});
// 詢問是否喜歡javascript
var oLabel2 = new sap.m.Label({
text: "Do you like JavaScript?"});
// 答案放在radioButton中
var oRadioBtnGrp2 = new sap.m.RadioButtonGroup({
columns: 2,
ariaLabelledBy: oLabel2,
buttons: [
new sap.m.RadioButton({text: "Yes"}),
new sap.m.RadioButton({text: "No" }),
]
});
new sap.ui.layout.Grid({
content: [
oImage1,
oImage2,
oLabel1,
oRadioBtnGrp1,
oLabel2,
oRadioBtnGrp2
]
}).placeAt("content");
};
sap.ui.getCore().attachInit(initialization);
</script>
</head>
<!-- UI area -->
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
注意代碼有兩個主要改變:
- Bootstrap 的
data-sap-ui-libs="sap.m, sap.ui.layout"
增加了sap.ui.layout
; - 控件全部放在 Grid layout 控件中而不是 DIV 中,只有 Grid 控件放在
DIV 中。Grid layout 控件和這些控件是聚合關系。主要代碼如下:
new sap.ui.layout.Grid({
content: [
oImage1,
oImage2,
oLabel1,
oRadioBtnGrp1,
oLabel2,
oRadioBtnGrp2
]
}).placeAt("content");
運行改變后的代碼,界面如下:
界面有改變,但兩個問題沒有分開,仍然不是我們想要的結果。我想把每個問題單獨放一行,答案一行。
控件的 layoutData 屬性
sap.ui.core.Element
類定義了 layoutData
屬性、getLayoutData()
方法和 setLayoutData()
方法。控件都是 sap.ui.core.Element
類的間接子類,從而控件都可以利用這些屬性和方法設定這個控件在頁面中如何定位。setLayoutData()
方法的參數是 sap.ui.core.LayoutData
對象。因為我們現在使用的 Grid 布局,所以 layoutData
我們可以用
sap.ui.core.LayoutData
類的子類 sap.ui.layout.GridData
。
以 sap.m.Label
控件為例,代碼這樣寫:
var oLabel1 = new sap.m.Label("label1", {
text : "Which logo do you like better?",
layoutData: new sap.ui.layout.GridData({
span: "XL12 L12 M12 S12"
})
});
調整后代碼如下:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8' />
<!-- Bootstrap -->
<script src="resources/sap-ui-core.js" id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m, sap.ui.layout"
data-sap-ui-theme="sap_bluecrystal">
</script>
<!-- Application area -->
<script>
function initialization() {
// 兩個image為兩個logo
var oImage1 = new sap.m.Image({
src : "img/alice.png",
decorative : false,
alt : 'Alice'
});
var oImage2 = new sap.m.Image({
src : "img/Hellen.png",
decorative : false,
alt : 'Helen'
});
// 詢問更喜歡哪一個logo
var oLabel1 = new sap.m.Label("label1", {
text : "Which logo do you like better?",
layoutData: new sap.ui.layout.GridData({
span: "XL12 L12 M12 S12"
})
});
// 答案放在radioButton中
var oRadioBtnGrp1 = new sap.m.RadioButtonGroup({
columns : 2,
ariaLabelledBy : oLabel1,
buttons : [
new sap.m.RadioButton({text : "Left logo"}),
new sap.m.RadioButton({text : "Right logo"}),
],
layoutData: new sap.ui.layout.GridData({
span: "XL12 L12 M12 S12"
})
});
// 詢問是否喜歡javascript
var oLabel2 = new sap.m.Label("label2", {
text : "Do you like JavaScript?",
layoutData: new sap.ui.layout.GridData({
span: "XL12 L12 M12 S12"
})
});
// 答案放在radioButton中
var oRadioBtnGrp2 = new sap.m.RadioButtonGroup({
columns : 2,
ariaLabelledBy : oLabel2,
buttons : [
new sap.m.RadioButton({text : "Yes"}),
new sap.m.RadioButton({text : "No"}),
],
layoutData: new sap.ui.layout.GridData({
span: "XL12 L12 M12 S12"
})
});
new sap.ui.layout.Grid({
content : [
oImage1,
oImage2,
oLabel1,
oRadioBtnGrp1,
oLabel2,
oRadioBtnGrp2 ]
}).placeAt("content");
};
sap.ui.getCore().attachInit(initialization);
</script>
</head>
<!-- UI area -->
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
調整后界面如下:
Responsive Margin
上面的界面中,控件和頁面沒有任何間距。我們可以在 div 的 class
屬性中添加 sapUiResponsiveMargin
來解決。
<!-- UI area -->
<body class="sapUiBody sapUiResponsiveMargin" role="application">
<div id="content"></div>
</body>
現在界面如下,在 Logo 上面有了一些間距 ( margin ):
達到目的。