如果多个控件都放在页面上,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 ):
达到目的。