鸿蒙初体验——JavaUI框架的布局方式分析
上次简单地编写了一个点击按钮切换图片的鸿蒙demo
今天简单分析下鸿蒙中的几个布局方式
注意:如题我使用的是鸿蒙的JavaUI框架而非jsUI框架,这篇文章只是简单地分析其中布局方式的类型并且与Android中的几种布局方式进行比较
如果想学习更详细的具体属性等知识点建议前往华为开发者联盟官网鸿蒙开发文档进行学习
xml文件绑定方式
当我们使用鸿蒙DevEcoStudio编译器创建鸿蒙应用后我们会发现默认创建的main页面MainAbility中并没有发现xml文件的绑定,这是怎么回事呢。
我们可以在MainAbility中的onStart方法中发现如下代码:
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
我们可以发现在MainRoute中引用了一个MainAbilitySlice的类我们点击进去,其实这个类就在我们的项目中的slice文件夹中
我们可以在MainAbilitySlice类中的onStart方法中就可以看到xml文件的绑定了
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
initView();
}
这就是在布局上面鸿蒙和Android的第一个区别了,我们看看鸿蒙官方是怎么说的
HarmonyOS提供了Ability和AbilitySlice两个基础类,一个有界面的Ability可以由一个或多个AbilitySlice构成,AbilitySlice主要用于承载单个页面的具体逻辑实现和界面UI,是应用显示、运行和跳转的最小单元。AbilitySlice通过setUIContent为界面设置布局。
由此我们可以知道在鸿蒙中xml是绑定在AbilitySlice类中,一个Ability可以包含多个AbilitySlice而每个AbilitySlice都可以有自己的xml类,所以我们就更加方便的编写同一个页面的不同布局方式
如果你是个Android开发者你应该很熟悉Android的xml绑定方式是在onCreate方法中setContentView(R.layout.***)但是鸿蒙却是super.setUIContent(ResourceTable.Layout_ability_main)。
其中与Android的使用R.的方式类似的是鸿蒙的layout与view都是使用ResourceTable,Android的R.后面根据你需要的类型可以使id,mipmap,drawable等等,鸿蒙则是你的layout名称或者view的命名名称前面加上类型下划线,如布局文件是ResourceTable.Layout_ability_main命名的组件是ResourceTable.Id_test_button。
下面我们来看下鸿蒙有哪些布局方式:
xml文件中怎么使用我就不贴代码了,自己动手才能明白不是吗,其实是我懒得写因为真的和Android的用发基本一模一样。
DirectionalLayout定向布局
DirectionalLayout的官方解释是用于将一组组件(Component)按照水平或者垂直方向排布,能够方便地对齐布局内的组件
其实也就是Android中的LinearLayout线性布局
DirectionalLayout的属性
排列方向(orientation):
水平(horizontal)垂直(vertical)默认为vertical
对齐方式(alignment):
left,top,right,bottom,horzontal_center,vertical_center,center,start,end可以设置单个值也可以使用“|”进行组合ohos:alignment="top|left"
子视图的权重和:total_weight
DirectionalLayout包含组件的属性
对齐方式(layout_alignment):
left,top,right,bottom,horzontal_center,vertical_center,center可以设置单个值也可以使用“|”进行组合ohos:layout_alignment="top|left"
比重(weight):weight
需要注意的是与Android相同组件使用layout_alignment控制自身在布局中的对齐方式,当对齐方式与排列方式方向一致时,对齐方式不会生效,如设置了水平方向的排列方式,则左对齐、右对齐将不会生效。
DependentLayout依赖布局
DependentLayout的官方解释为:每个组件可以指定相对于其他同级元素的位置,或者指定相对于父组件的位置
其实就相当于Android的RelativeLayout相对布局
DependentLayout的属性
对齐方式(alignment):
left,top,right,bottom,horzontal_center,vertical_center,center可以设置单个值也可以使用“|”进行组合ohos:layout_alignment="top|left"
DependentLayout包含组件的属性
其中引用方式相同ohos:left_of="$id:component_id"
下面不做重复说明
left_of:将右边缘与另一个子组件的左边缘对齐
right_of:将左边缘与另一个子组件的右边缘对齐
start_of:将结束边与另一个子组件的起始边对齐
end_of:将起始边与另一个子组件的结束边对齐
above:将下边缘与另一个子组件的上边缘对齐
below:将上边缘与另一个子组件的下边缘对齐
align_baseline:将子组件的基线与另一个子组件的基线对齐
align_left:将左边缘与另一个子组件的左边缘对齐
align_top:将上边缘与另一个子组件的上边缘对齐
align_right:将右边缘与另一个子组件的右边缘对齐
align_bottom:将底边与另一个子组件的底边对齐
align_start:将起始边与另一个子组件的起始边对齐
align_end:将结束边与另一个子组件的结束边对齐
align_parent_left:将左边缘与父组件的左边缘对齐
align_parent_top:将上边缘与父组件的上边缘对齐
align_parent_right:将右边缘与父组件的右边缘对齐
align_parent_bottom:将底边与父组件的底边对齐
align_parent_start:将起始边与父组件的起始边对齐
align_parent_end:将结束边与父组件的结束边对齐
center_in_parent:将子组件保持在父组件的中心
horizontal_center:将子组件保持在父组件水平方向的中心
vertical_center:将子组件保持在父组件垂直方向的中心
StackLayout堆布局
StackLayout的官方解释:直接在屏幕上开辟出一块空白的区域,添加到这个布局中的视图都是以层叠的方式显示,而它会把这些视图默认放到这块区域的左上角,第一个添加到布局中视图显示在最底层,最后一个被放在最顶层。上一层的视图会覆盖下一层的视图。
相当于Android中的FrameLayout帧布局
StackLayout包含的组件属性
对齐方式(layout_alignment):
left,top,right,bottom,horzontal_center,vertical_center,center可以设置单个值也可以使用“|”进行组合ohos:layout_alignment="top|left"
TableLayout表格布局
这个与Android中的TableLayout是一模一样的
TableLayout的属性
对齐方式(alignment_type):
align_edges:TableLayout内的组件按边界对齐
align_contents:TableLayout内的组件按边距对齐
column_count:列数
row_count:行数
排列方向(orientation):
horizontal:水平
vertical:垂直
PositionLayout位置布局
PositionLayout的官方解释:子组件通过指定准确的x/y坐标值在屏幕上显示。(0, 0)为左上角;当向下或向右移动时,坐标值变大;允许组件之间互相重叠。
相当于Android中的AbsoluteLayout绝对布局
其属性就是在其中创建组件,并通过position_x和position_y属性设置子组件的坐标
AdaptiveBoxLayout自适应盒子布局
我们先来看下鸿蒙官方是怎么介绍的
该布局提供了在不同屏幕尺寸设备上的自适应布局能力,主要用于相同级别的多个组件需要在不同屏幕尺寸设备上自动调整列数的场景。
1、该布局中的每个子组件都用一个单独的“盒子”装起来,子组件设置的布局参数都是以盒子作为父布局生效,以整个自适应布局为生效范围。
2、该布局中每个盒子的宽度固定为布局总宽度除以自适应得到的列数,高度为match_content,每一行中的所有盒子按高度最高的进行对齐。
3、该布局水平方向是自动分块,因此水平方向不支持match_content,布局水平宽度仅支持match_parent或固定宽度。
4、自适应仅在水平方向进行了自动分块,纵向没有做限制,因此如果某个子组件的高设置为match_parent类型,可能导致后续行无法显示。
如果你和我一样是Android开发的话看见这个布局方式应该会比较陌生,但是如果你是web、vue等大前端开发者的话你肯定很熟悉,就相当于弹性盒子布局。
AdaptiveBoxLayout常用方法
addAdaptiveRule(int minWidth, int maxWidth, int columns)添加一个
removeAdaptiveRule(int minWidth, int maxWidth, int columns)移除一个
clearAdaptiveRules()移除所有
Java中代码如下:
AdaptiveBoxLayout adaptiveBoxLayout = (AdaptiveBoxLayout)findComponentById(ResourceTable.Id_adaptive_box_layout);
findComponentById(ResourceTable.Id_add_rule_btn).setClickedListener((component-> {
// 添加规则
adaptiveBoxLayout.addAdaptiveRule(100, 2000, 3);
// 更新布局
adaptiveBoxLayout.postLayout();
}));
findComponentById(ResourceTable.Id_remove_rule_btn).setClickedListener((component-> {
// 移除规则
adaptiveBoxLayout.removeAdaptiveRule(100, 2000, 3);
// 更新布局
adaptiveBoxLayout.postLayout();
}));
以上就是鸿蒙现有的六种布局方式,如果你以前是Android开发或者前端开发的话应该是很熟悉的,大部分属性都是相同的只是名称不同。
在上面的java代码块中你可以看到鸿蒙中组件的具体引用方式,和目前的Android写法有所不同的只是名称与我前面所讲的ResourceTable.的不同,还有注意鸿蒙目前是需要强转的这个是我不太喜欢的地方因为Android已经不需要强转很久了
其他
还有一点就是DevEcoStudio中你在xml文件中编写在Previewer不能实时更新,需要你手动Ctrl+s或者点击编译器外才会更新,建议能够修改体验还是有点不好。
鸿蒙的常用组件我就不写文章了因为觉得没啥大的区别只是部分属性的名称变化,而且实在太多了一个一个写不太现实
下一篇鸿蒙初体验打算写自定义组件与布局,具体时间不定因为最近在使用kotlin重构公司老项目,14年的项目而且经历人手太多了,只能一点点抽丝剥茧不太有时间。
感谢观看!
如果文中有错误的话还请大家及时评论指出,我会及时修改。