想了解更多内容,板学请访问:
和华为官方合作共建的板学鸿蒙技术社区
https://harmonyos.51cto.com
使用Java语言开发,用于Phone设备的板学Feature Ability模板,使用XML布局。板学
展示了一个名片详情页的板学样例工程,主要由一个ScrollView嵌套的板学两个ListContainer组成。
安装DevEco Studio,板学详情请参考DevEco Studio下载。板学
设置DevEco Studio开发环境,板学DevEco Studio开发环境需要依赖于网络环境,板学需要连接上网络才能确保工具的板学正常使用,可以根据如下两种情况来配置开发环境:
如果可以直接访问Internet,板学只需进行下载HarmonyOS SDK操作。板学
如果网络不能直接访问Internet,板学需要通过代理服务器才可以访问,板学请参考配置开发环境。
功能逻辑代码
└─businesscardabilityjava │ MainAbility.java │ MyApplication.java │ ├─datamodel //数据模型 │ DefaultDoubleLineListItemInfo.java │ ItemInfo.java │ SingleButtonDoubleLineListItemInfo.java │ ├─itemprovider //子项提供者 │ ListItemProvider.java │ ├─slice //核心页面 │ MainAbilitySlice.java │ ├─typefactory //列表类型工厂 │ ListTypeFactory.java │ TypeFactory.java │ └─viewholder //视图持有者 DefaultDoubleLineList.java SingleButtonDoubleLineList.java ViewHolder.java布局及样式代码
└─resources ├─base │ ├─element │ │ color.json //存储了页面的一些颜色值 │ │ float.json │ │ string.json │ │ │ ├─graphic │ │ bottom_tab_background.xml //tab栏背景样式 │ │ card_background.xml //卡片背景样式 │ │ divider.xml //分割线样式 │ │ ic_about.xml │ │ ic_actived.xml │ │ ic_add.xml │ │ ic_back.xml │ │ ic_call.xml │ │ ic_chat.xml │ │ ic_edit.xml //编辑tab按钮icon │ │ ic_edit_actived.xml //激活状态编辑tab按钮icon │ │ ic_enabled.xml │ │ ic_favorite.xml //收藏tab按钮icon │ │ ic_favorite_actived.xml //激活状态收藏tab按钮icon │ │ ic_header.xml //联系人头像icon │ │ ic_more.xml │ │ ic_mores.xml //更多tab按钮icon │ │ ic_mores_actived.xml //激活状态更多tab按钮icon │ │ ic_next.xml │ │ ic_normal.xml │ │ ic_qrcode.xml │ │ ic_video.xml │ │ │ ├─layout │ │ ability_main.xml //名片主页面 │ │ default_doublelinelist.xml //默认双行列表项组件页面 │ │ singlebutton_doublelinelist.xml //单按钮双行列表项组件页面 │ │ tab.xml //tab按钮组件页面 │ │ │ ├─media │ │ icon.png │ │ ic_next.png │ │ ic_update.png │ │ like_icon.jpg │ │ profile.png │ │ profile_mask.png │ │ search.jpg │ │ share_icon.jpg │ │ │ └─profile └─rawfile本页面的布局包括DependentLayout和DirectionalLayout布局,由ScrollView、ListContainer、Image、Text组件共同来构成,整体分为上中下布局。
上方是应用工具栏,使用了DirectionalLayout嵌套横向布局,布局中用Image组件提供了返回和二维码的功能,网站模板2个布局权重是1:1。
中间是联系人的头像和姓名以及联系人其它信息列表,由于列表长度不固定采用了ScrollView组件,内部使用DependentLayout布局嵌套的方式,用DependentLayout包裹ListContainer组件用于列表的展示,其中列表项是由后台通过自定义的2行列表组件动态创建。
底部是联系人可操作的功能区,包括收藏、编辑、更多,采用了DirectionalLayout 嵌套布局,外层DirectionalLayout 用户背景显示,内层DirectionalLayout 用户内容的显示,其中内容的显示是通过自定义tab组件由后台动态创建实现的。
页面在resources\base\layout\ability_main.xml 代码如下:
<?xml version="1.0" encoding="utf-8"?> <DependentLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:id="$+id:root_layout" ohos:height="match_parent" ohos:width="match_parent" ohos:orientation="vertical"> <DirectionalLayout ohos:id="$+id:background" ohos:height="match_parent" ohos:width="match_parent" ohos:align_parent_top="true" ohos:background_element="$color:color_background"/> <DirectionalLayout ohos:id="$+id:appBar" ohos:height="match_content" ohos:width="match_parent" ohos:align_parent_top="true" ohos:end_padding="$float:max_padding_appBar" ohos:layout_direction="locale" ohos:orientation="horizontal" ohos:start_padding="$float:max_padding_start"> <DirectionalLayout ohos:id="$+id:appBar_leftPart" ohos:height="$float:height_backButton_touchTarget" ohos:width="0vp" ohos:alignment="center" ohos:orientation="horizontal" ohos:weight="1"> <Image ohos:id="$+id:appBar_backButton" ohos:height="$float:height_appBar_Buttons" ohos:width="$float:width_appBar_buttons" ohos:image_src="$graphic:ic_back"/> <Text ohos:id="$+id:appBar_userName" ohos:height="match_parent" ohos:width="match_parent" ohos:alpha="0" ohos:left_margin="$float:leftMargin_userName" ohos:text="$string:title_contactsDetail" ohos:text_size="$float:textSize_userName"/> </DirectionalLayout> <DirectionalLayout ohos:id="$+id:appBar_rightPart" ohos:height="match_parent" ohos:width="0vp" ohos:alignment="vertical_center|right" ohos:focusable_in_touch="false" ohos:orientation="horizontal" ohos:start_margin="$float:start_margin_appBar" ohos:weight="1"> <DirectionalLayout ohos:id="$+id:appBar_button3_touchTarget" ohos:height="$float:height_touchTarget" ohos:width="$float:width_touchTarget" ohos:alignment="center"> <Image ohos:id="$+id:appBar_button3" ohos:height="$float:height_appBar_Buttons" ohos:width="$float:width_appBar_buttons" ohos:image_src="$graphic:ic_qrcode"/> </DirectionalLayout> </DirectionalLayout> </DirectionalLayout> <ScrollView ohos:id="$+id:contacts_detail_scroll" ohos:height="match_parent" ohos:width="match_parent" ohos:below="$id:appBar" ohos:bottom_margin="$float:height_bottom_tab"> <DependentLayout ohos:id="$+id:contacts_detail" ohos:height="match_content" ohos:width="match_parent" ohos:orientation="vertical"> <DependentLayout ohos:id="$+id:contacts_detail_upperCard" ohos:height="match_content" ohos:width="match_parent" ohos:align_parent_top="true" ohos:background_element="$graphic:card_background" ohos:left_padding="$float:max_padding_start" ohos:orientation="vertical" ohos:right_padding="$float:max_padding_end" ohos:top_margin="$float:topMargin_contactsDetail_upperCard"> <ListContainer ohos:id="$+id:contacts_detail_upperCard_list" ohos:height="0vp" ohos:width="match_parent" ohos:below="$+id:contacts_detail_title"/> </DependentLayout> <Image ohos:id="$+id:contacts_detail_profile" ohos:height="$float:height_contacts_profile" ohos:width="$float:width_contacts_profile" ohos:align_parent_top="true" ohos:alpha="1" ohos:center_in_parent="true" ohos:image_src="$graphic:ic_header" ohos:top_margin="$float:topMargin_contacts_profile"/> <Text ohos:id="$+id:contacts_detail_title" ohos:height="match_content" ohos:width="match_parent" ohos:align_parent_top="true" ohos:text="$string:title_contactsDetail" ohos:text_alignment="horizontal_center" ohos:text_size="$float:textSize_contactsDetail_title" ohos:top_margin="$float:topMargin_contactsDetail_title"/> </DependentLayout> </ScrollView> <DirectionalLayout ohos:id="$+id:bottom_tab" ohos:height="$float:height_bottom_tab" ohos:width="match_parent" ohos:align_parent_bottom="true" ohos:alignment="vertical_center" ohos:background_element="$graphic:bottom_tab_background" ohos:left_padding="$float:max_padding_start" ohos:right_padding="$float:max_padding_end"> <DirectionalLayout ohos:id="$+id:bottom_tabMenu" ohos:height="match_content" ohos:width="match_parent" ohos:orientation="horizontal"/> </DirectionalLayout> </DependentLayout>本页面的布局包括DirectionalLayout布局,由Image、Text组件共同来构成,整体是横向布局,云服务器布局如下:
页面在resources\layout\default_doublelinelist.xml ,代码如下:
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:id="$+id:default_doubleLineList" ohos:height="$float:height_doubleLineList" ohos:width="match_parent" ohos:orientation="vertical"> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:id="$+id:doubleLineList" ohos:height="$float:height_doubleLineList_text" ohos:width="match_parent" ohos:bottom_margin="$float:bottomMargin_doubleLineList" ohos:orientation="horizontal" ohos:top_margin="$float:topMargin_doubleLineList"> <DirectionalLayout ohos:id="$+id:doubleLineList_text" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="vertical_center" ohos:orientation="vertical" ohos:weight="2"> <DirectionalLayout ohos:id="$+id:doubleLineList_text_layout" ohos:height="match_parent" ohos:width="match_content" ohos:layout_direction="locale"> <Text ohos:id="$+id:doubleLineList_text_primary" ohos:height="match_content" ohos:width="match_parent" ohos:bottom_margin="$float:bottomMargin_doubleLineList" ohos:layout_direction="locale" ohos:text_color="$color:color_doubleLineList_primary_text" ohos:text_size="$float:textSize_primaryText"/> <Text ohos:id="$+id:doubleLineList_text_secondary" ohos:height="match_content" ohos:width="match_parent" ohos:layout_direction="locale" ohos:text_color="$color:color_doubleLineList_secondary_text" ohos:text_size="$float:textSize_secondaryText"/> </DirectionalLayout> </DirectionalLayout> <DirectionalLayout ohos:id="$+id:doubleLineList_right" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="vertical_center|right" ohos:orientation="horizontal" ohos:right_of="$+id:doubleLineList_text" ohos:weight="2"> <DirectionalLayout ohos:id="$+id:doubleLineList_right_touchTarget1" ohos:height="$float:height_touchTarget" ohos:width="$float:width_touchTarget" ohos:alignment="center"> <Image ohos:id="$+id:doubleLineList_right_img1" ohos:height="$float:height_doubleLineList_button" ohos:width="$float:width_doubleLineList_button"/> </DirectionalLayout> <DirectionalLayout ohos:id="$+id:doubleLineList_right_touchTarget2" ohos:height="$float:height_touchTarget" ohos:width="$float:width_touchTarget" ohos:alignment="center"> <Image ohos:id="$+id:doubleLineList_right_img2" ohos:height="$float:height_doubleLineList_button" ohos:width="$float:width_doubleLineList_button"/> </DirectionalLayout> <DirectionalLayout ohos:id="$+id:doubleLineList_right_touchTarget3" ohos:height="$float:height_touchTarget" ohos:width="$float:width_touchTarget" ohos:alignment="center"> <Image ohos:id="$+id:doubleLineList_right_img3" ohos:height="$float:height_doubleLineList_button" ohos:width="$float:width_doubleLineList_button"/> </DirectionalLayout> </DirectionalLayout> </DirectionalLayout> <Image ohos:id="$+id:divider" ohos:height="$float:height_divider" ohos:width="match_parent" ohos:image_src="$graphic:divider"/> </DirectionalLayout>本页面和默认双行列表组件页面基本一致,只是布局中只有一个操作按钮,使用DirectionalLayout布局,由Image、Text组件共同来构成,整体是横向布局,布局如下:
页面在/resources/base/layout/singlebutton_doublelinelist.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:id="$+id:singleButton_doubleLineList" ohos:height="$float:height_doubleLineList" ohos:width="match_parent" ohos:orientation="vertical"> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:id="$+id:singleButtonList" ohos:height="$float:height_doubleLineList_text" ohos:width="match_parent" ohos:bottom_margin="$float:bottomMargin_doubleLineList" ohos:orientation="horizontal" ohos:top_margin="$float:topMargin_doubleLineList"> <DirectionalLayout ohos:id="$+id:singleButtonList_text" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="vertical_center" ohos:orientation="vertical" ohos:weight="2"> <DirectionalLayout ohos:height="match_parent" ohos:width="match_content" ohos:layout_direction="locale"> <Text ohos:id="$+id:singleButtonList_text_primary" ohos:height="match_content" ohos:width="match_content" ohos:bottom_margin="$float:bottomMargin_doubleLineList" ohos:layout_direction="locale" ohos:text_color="$color:color_doubleLineList_primary_text" ohos:text_size="$float:textSize_primaryText"/> <Text ohos:id="$+id:singleButtonList_text_secondary" ohos:height="match_content" ohos:width="match_content" ohos:layout_direction="locale" ohos:text_color="$color:color_doubleLineList_secondary_text" ohos:text_size="$float:textSize_secondaryText"/> </DirectionalLayout> </DirectionalLayout> <DirectionalLayout ohos:id="$+id:singleButtonList_right" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="vertical_center|right" ohos:layout_direction="locale" ohos:weight="1"> <DirectionalLayout ohos:height="match_content" ohos:width="match_content" ohos:layout_direction="locale"> <DirectionalLayout ohos:id="$+id:singleButtonList_right_touchTarget" ohos:height="$float:height_touchTarget" ohos:width="$float:width_touchTarget" ohos:alignment="center"> <Image ohos:id="$+id:singleButtonList_right_img" ohos:height="$float:height_doubleLineList_switch" ohos:width="$float:width_doubleLineList_switch"/> </DirectionalLayout> </DirectionalLayout> </DirectionalLayout> </DirectionalLayout> <Image ohos:id="$+id:divider" ohos:height="$float:height_divider" ohos:width="match_parent" ohos:image_src="$graphic:divider"/> </DirectionalLayout>自定义的tab组件,用于动态渲染tab栏,使用DirectionalLayout布局,由Image、Text组件共同来构成,整体是垂直布局。
页面在resources/base/layout/tab.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:id="$+id:tab" ohos:height="match_content" ohos:width="0vp" ohos:alignment="center" ohos:orientation="vertical" ohos:weight="1"> <Image ohos:id="$+id:bottom_tab_button_image" ohos:height="$float:height_tab" ohos:width="$float:width_tab" /> <Text ohos:id="$+id:bottom_tab_button_text" ohos:height="match_content" ohos:width="match_parent" ohos:text_alignment="top|horizontal_center" ohos:text_color="$color:color_tabText_normal" ohos:text_size="$float:textSize_tab" /> </DirectionalLayout>说明:
布局文件中使用到了一些样式和图片,在resources\base\graphic下有做定义,详情可以参考完整代码。
不需要额外申请权限
将动态添加的tab按钮存储到List中并进行遍历,设置当前点击的tab按钮为激活样式,其它tab按钮设置为普通效果。
后台代码在 /slice/MainAbilitySlice.java 关键代码如下:
tab.setClickedListener(component -> { Text focusTab = (Text) component.findComponentById(ResourceTable.Id_bottom_tab_button_text); //Set active tab image setActiveTabImage(tabList, focusTab.getText()); }); /** * * @param tabList tab按钮列表 * @param focusText 需要激活的tab名称 */ private void setActiveTabImage(List<DirectionalLayout> tabList, String focusText) { Element tabNormal = null; Element tabActived = null; for (DirectionalLayout btn : tabList) { Text text = (Text) btn.findComponentById(ResourceTable.Id_bottom_tab_button_text); if ("收藏".equals(text.getText())) { tabNormal = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_ic_favorite); tabActived = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_ic_favorite_actived); if ("收藏".equals(focusText)) { ((Image) btn.findComponentById(ResourceTable.Id_bottom_tab_button_image)).setImageElement(tabActived); } else { ((Image) btn.findComponentById(ResourceTable.Id_bottom_tab_button_image)).setImageElement(tabNormal); } } if ("编辑".equals(text.getText())) { tabNormal = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_ic_edit); tabActived = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_ic_edit_actived); if ("编辑".equals(focusText)) { ((Image) btn.findComponentById(ResourceTable.Id_bottom_tab_button_image)).setImageElement(tabActived); } else { ((Image) btn.findComponentById(ResourceTable.Id_bottom_tab_button_image)).setImageElement(tabNormal); } } if ("更多".equals(text.getText())) { tabNormal = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_ic_mores); tabActived = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_ic_mores_actived); if ("更多".equals(focusText)) { ((Image) btn.findComponentById(ResourceTable.Id_bottom_tab_button_image)).setImageElement(tabActived); } else { ((Image) btn.findComponentById(ResourceTable.Id_bottom_tab_button_image)).setImageElement(tabNormal); } } } }向上/下滑动滚动条,显示和隐藏顶部应用栏中联系人姓名(通过设置文字透明度实现)和更改背景的效果(更改背景色)
后台代码在 /slice/MainAbilitySlice.java 关键代码如下:
private void initScrollView() { ScrollView scrollView = (ScrollView) findComponentById(ResourceTable.Id_contacts_detail_scroll); int profileSizePx = AttrHelper.vp2px(COLOR_CHANGE_RANGE, this); if (scrollView != null) { scrollView.setReboundEffectParams(OVERSCROLL_PERCENT, OVERSCROLL_RATE, REMAIN_VISIBLE_PERCENT); scrollView.setReboundEffect(true); //获取appbar显示的源码库contact name Text userName = (Text) findComponentById(ResourceTable.Id_appBar_userName); DirectionalLayout backGround = (DirectionalLayout) findComponentById(ResourceTable.Id_background); ShapeElement shapeElement = new ShapeElement(); shapeElement.setShape(ShapeElement.RECTANGLE); // Set Scrolled listener scrollView.getComponentTreeObserver().addScrolledListener(() -> { float curY = scrollView.getScrollValue(Component.AXIS_Y); HiLog.info(LABEL, "curY:" + curY); int colorChange = (int) ((BACKGROUND_COLOR - ORIGINAL_BACKGROUND_COLOR) * curY / profileSizePx); HiLog.info(LABEL, "colorChange:" + colorChange); HiLog.info(LABEL, "colorValue:" + (ORIGINAL_BACKGROUND_COLOR + colorChange)); //设置颜色的方法 //1.设置ability_main.xml组件中的背景色,如:240/160/110,这是一个橙色 //2.手动加上刚才的值,如240/160/110 shapeElement.setRgbColor(new RgbColor(ORIGINAL_BACKGROUND_COLOR + colorChange+240, ORIGINAL_BACKGROUND_COLOR + colorChange+160, ORIGINAL_BACKGROUND_COLOR + colorChange+110)); backGround.setBackground(shapeElement); userName.setAlpha(1 * curY / profileSizePx); }); } }效果展示:
向下滚动
向上滚动
点击tab图标
文章相关附件可以点击下面的原文链接前往下载
https://harmonyos.51cto.com/posts/4776
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com