DeviceOne平台包含2个基础的布局组件,do_ALayout
和do_Linearlayout
。所谓布局组件就是在IDE里设计界面,可以拖拽别的组件加到这个布局组件里作为这个布局组件内的一个部分。
注意:do_ScrollView也算是布局,也可以往里面拖拽其他组件,不过它比较特殊,它有且只有一个子节点。我们这里暂时不讨论。
do_ALayout组件
这个是最基础最常用的布局组件,这里的 ALayout
是AbsoluteLayout
的缩写,表示绝对布局。绝对布局使用很简单,它内部的所有组件的布局都是绝对坐标值,不过这个坐标值是相对ALayout来说的,不是相对整个屏幕。
如下图,按钮的x,y坐标都是100,是相对于按钮所在的ALayout的左上角。
这个组件的API可以参考这里.我们重点的介绍几个重要的特性:
do_ALayout可以设置背景图片,这个功能比较常见,就是设置bgImage属性。
do_ALayout支持
touch
,touchDown
,touchUp
事件,这里有一个技巧就是,在do_ALayout上添加一个do_Imageview, 如果在imageview上添加点击事件,用户手指必须点中图片才能激活,但是如果把事件加到imageview所在的ALayout,那么可点击区域就很大了,用户体验会好很多。
如下图,上面的touch事件加在iamgeview上,手指会很难点中。示例代码下载参考这里属性
isStretch
和layoutAlign
,这二个属性很重要,涉及到屏幕适配的一个方式,解决在不同的手机屏幕宽高比不一样导致的变形问题。更详细的说明参考这里add
方法,do_ALayout和do_LinearLayout都具有这个方法,原理也一样。add
这个方法也非常重要,通过这个方法可以在app运行是动态增加ui。应用的场景就是一些ui可以重复使用,比如一个app中所有的页面的header都是类似的,可以通过add
动态添加,然后更新数据。更大的好处是能把这个add
进去的ui对应的逻辑代码写在这个ui对应的js文件里。可以降低代码的耦合度。
参考这个示例,主要代码如:
var nf = sm("do_Notification");
var page = sm("do_Page");
var layout = ui("ALayout_1");
// 把header.ui的根节点(是一个id为root的ALayout)加到当前index.ui的0,0位置
// 并且重新给它命名一个新的唯一标示id "header_id", 这个id不要和index.ui里已有的ui组件的id重复
var addedheader = layout.add("header_id", "source://view/header.ui", 0, 0);
// 获取header.ui的根节点对象(是一个id为root的ALayout),但是我们不能通过
// var header = ui("root");来获取这个对象,因为root这个id的作用域是在header.ui,而不是在index.ui.js
// 正确的写法是有2种,第一是:
var header1 = ui("header_id");
// 第二是:
var header2 = ui(addedheader);
// 判断这二个对象是否相同,可以通过getAddress方法
nf.toast(header1.getAddress() == header2.getAddress());
// 进一步我们还可以获取到header.ui根节点之下的子节点,比如statusbar是header.ui最上面的一部分组件的id
var statusbar = ui(addedheader + ".statusbar");
statusbar.bgColor = "FF0000FF";
// 我们并不推荐在index.ui里直接获取header.ui 的子对象,这不符合降低耦合度的原则
// index.ui不能直接调用header.ui里的函数,因为它们处于不同的js运行环境
// 要实现这二者之间的数据交换,可以通过二种方式
// 第一:通过数据bind,在header.ui.js里setmapping,然后通过binddata给header赋值
var hashdata = mm("do_HashData");
header1.bindData(hashdata);
hashdata.addData({
"title_value" : "我是首页",
"menu_bg_value" : "FF0000FF"
})
header1.refreshData();
// 第二:通过消息机制,订阅和触发消息都在page对象,因为header.ui和index.ui在同一page下
page.on("click_menu", function(data) {
nf.alert(data);
})
do_LinearLayout组件
LinearLayout组件叫线性布局,意思就是里面的组件按线性排列,可以上下,可以左右排列。里面所有的子view的x,y没有意义,因为它们是一个接一个,无缝的拼接在一起。
这个组件的API可以参考这里.
我们重点的介绍几个重要的特性:
LinearLayout很少设置固定的高度和宽度,它最大的优势是可以动态根据内容来变化width和height,自适应大小,强制性地使视图扩展以便显示其全部内容,也就是
WRAP_CONTENT
。Do平台有不少组件支持这种方式,参考文档.
具体就是设置LinearLayout的width或height为-1表示自适应。那么LinearLayout显示的真实高度和宽度就是由它里面的所有子view叠加起来的。padding和margin属性,其实margin是所有ui都具有的公共属性,但是它只能在Linearlayout里有效,所以在这里一起提一下。
padding就是在LinearLayout的内边距,margin就是LinearLayout里的一个子view和相邻的组件的距离,比如:add方法,LinearLayout 原理和do_ALayout完全一样,只不过就是参数x,y改成一个id值,表示加到现有一个组件的后面或下面。
参考这个示例