一. 效果展示
二. 知识点分解
1. 基础组件使用
以Tabs组件为基础,其中有2个TAB分别展示了“首页”TAB和“项目”TAB,本例中项目TAB下无内容。仅作为展示Tabs组件所用。
Tabs通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。 需要配合TabContent组件使用,TabContent仅在Tabs中使用,对应一个切换页签的内容视图。
首页顶部放置的Swiper组件, 滑块视图容器,提供子组件滑动轮播显示的能力。
- Web
提供具有网页显示能力的Web组件,@ohos.web.webview 提供web控制能力。
2. 页面跳转
@system.router (页面路由) 通过不同的uri访问不同的页面。
本例中,在点击Swiper组件内容或文章列表项后,跳转到应用内的Web页面。
3. 网络请求
参考鸿蒙官方sample代码,对http数据请求进行了简单封装。可以进行get类型的请求发送。
4. 引入三方库
由于鸿蒙原生List控件并没有下拉刷新和上拉加载功能,并且在开发者官网给出支持下拉刷新和上拉加载的demo使用起来并不方便。所以本例中使用了三方库,该引入的三方库在实现列表下拉和上拉操作时会方便许多。
这也是三方库能够加速app开发的重要特性。 本例中就以引入该三方列表库来展示如何在鸿蒙开发中引入静态三方库。
三. 具体实现
首先需要建立首页结构。在MainPage中加入Tabs组件,在Tabs中加入TabContent.
@Builder TabBuilder(title: string, index: number, icon: Resource) {
Column() {
Image(icon)
.width($r('app.float.mainPage_baseTab_size'))
.height($r('app.float.mainPage_baseTab_size'))
.fillColor(this.getTabBarColor(index))
Text(title)
.margin({ top: $r('app.float.mainPage_baseTab_top') })
.fontSize($r('app.float.main_tab_fontSize'))
.fontColor(this.getTabBarColor(index))
}
.justifyContent(FlexAlign.Center)
.height($r('app.float.mainPage_barHeight'))
.width(Constants.FULL_PARENT)
.onClick(() => {
this.currentTabIndex = index;
this.tabsController.changeIndex(this.currentTabIndex)
})
}
build() {
Tabs({
barPosition: BarPosition.End,
controller: this.tabsController
}) {
// 首页
TabContent() {
Home()
}
.padding({ left: $r('app.float.mainPage_padding'), right: $r('app.float.mainPage_padding') })
.backgroundColor($r('app.color.mainPage_backgroundColor'))
.tabBar(this.TabBuilder(Constants.HOME_TITLE, Constants.HOME_TAB_INDEX
, $r('app.media.ic_bottom_home')))
// 项目
TabContent() {
Project()
}
.padding({ left: $r('app.float.mainPage_padding'), right: $r('app.float.mainPage_padding') })
.backgroundColor($r('app.color.mainPage_backgroundColor'))
.tabBar(this.TabBuilder(Constants.PROJECT_TITLE, Constants.PROJECT_TAB_INDEX
, $r('app.media.ic_bottom_project')))
}
.width(Constants.FULL_PARENT)
.backgroundColor(Color.White)
.barHeight($r('app.float.mainPage_barHeight'))
.barMode(BarMode.Fixed)
.onChange((index: number) => {
this.currentTabIndex = index;
})
}
Home中由一个Banner自定义组件和ArticleList自定义组件构成
@Component
export default struct Home {
build() {
Stack() {
ArticleList();
Banner();
}.alignContent(Alignment.Top)
}
}
Banner组件中进行Banner数据请求并填充到Swiper组件中。
对于组件的 aboutToAppear 和 aboutToDisappear 在开发过程中会比较常用到。
aboutToAppear函数在创建自定义组件的新实例后,在执行其build函数之前执行。允许在aboutToAppear函数中改变状态变量,更改将在后续执行build函数中生效。
aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。
aboutToAppear() {
HomeViewModel.getHomeBanner(Constants.GET_HOME_BANNER).then((data: HomeBannerItemBean[]) => {
this.bannerData = data;
}).catch((err: string | Resource) => {
promptAction.showToast({
message: err,
duration: Constants.ANIMATION_DURATION
});
});
}
build() {
Column() {
Swiper(this.swiperController) {
ForEach(this.bannerData, (banner: HomeBannerItemBean) => {
Image(banner.imagePath).borderRadius($r('app.float.home_swiper_borderRadius')).onClick(() => {
router.pushUrl({
url: 'pages/WebPage',
params: {
title: banner.title,
src: banner.url
}
}, router.RouterMode.Single)
})
}, (img: Resource) => JSON.stringify(img.id))
}
.margin({top: $r('app.float.home_swiper_margin')})
.autoPlay(true)
.width(Constants.FULL_PARENT)
.height($r('app.float.main_swiper_height'))
}
}
文章列表实现, 也是在aboutToAppear中进行数据请求。可以看到这里使用的三方组件ListView很轻松的实现了目标功能。
aboutToAppear() {
this.getHomeArticleList(true);
}
@Builder
itemLayout(item, index) {
ArticleItem({articleData: item})
}
getHomeArticleList(reset: boolean) {
HomeViewModel.getHomeArticleList(this.currentPage, this.pageSize, Constants.GET_HOME_ARTICLE_LIST)
.then((data: ArticleDataBean) => {
if (data.curPage < data.pageCount) {
this.currentPage++;
this.hasMore = true;
} else {
this.hasMore = false;
}
if (reset) {
this.articleData = data.datas;
} else {
this.articleData = this.articleData.concat(data.datas);
}
}).catch((err: string | Resource) => {
promptAction.showToast({ message: err});
})
}
build() {
ListView({
items: this.articleData, //数据源 数组
itemLayout: (item, index) => this.itemLayout(item, index),
controller: this.controller, //控制器,负责关闭下拉和上拉
marginHeader: 160,
onRefresh: () => {
//下拉刷新
this.getHomeArticleList(true);
this.controller.finishRefresh()
},
onLoadMore: () => {
//上拉加载
this.getHomeArticleList(false);
this.controller.finishLoadMore()
}
})
}
新建WebPage, 封装Web组件实现网页的展示。 WebPage接受src参数作为页面url, 接受title参数作为标题栏文字。
import router from '@ohos.router';
import web_webview from '@ohos.web.webview'
import Constants from '../common/Constants';
@Entry
@Component
struct WebPage {
@State src: string = router.getParams()?.['src'];
@State title: string = router.getParams()?.['title'];
controller: web_webview.WebviewController = new web_webview.WebviewController();
build() {
Column() {
PageTitle({ titleName: this.title })
Divider()
.strokeWidth('1px')
.color($r('sys.color.ohos_id_color_list_separator'))
Web({
src: this.src, controller: this.controller
}).javaScriptAccess(true)
}
}
}
@Component
struct PageTitle {
private titleName: string
build() {
Row() {
Image($r('app.media.back'))
.width(20)
.height(20)
.onClick(() => {
router.back()
})
Text(this.titleName)
.fontSize(Constants.PAGE_TITLE_TEXT_SIZE)
.width(Constants.PAGE_TITLE_TEXT_WIDTH)
.maxLines(Constants.PAGE_TITLE_TEXT_MAX_LINES)
.textOverflow({overflow: TextOverflow.Ellipsis})
.margin({ left: 20 })
}
.padding(12)
.width('100%')
}
}
该配置位于ets/resources/base/profile/main_pages.json
{
"src": [
"pages/MainPage",
"pages/WebPage"
]
}
网络请求方法封装, 实际项目中可以考虑换成其他三方库来实现网络请求。以实现Header拦截,error拦截等操作,以及其他如post类型等其他常见需求。
本例中使用的开放接口来自WanAndroid大神的无私奉献,此例中仅使用了2个接口。大家如有兴趣可以参考并自行实现全部接口。
/**
* Initiates an HTTP request to a given URL.
*
* @param url URL for initiating an HTTP request.
* @param params Params for initiating an HTTP request.
*/
export function httpRequestGet(url: string): Promise<ResponseResult> {
let httpRequest = http.createHttp();
let responseResult = httpRequest.request(url, {
method: http.RequestMethod.GET,
readTimeout: Constants.HTTP_READ_TIMEOUT,
header: {
'Content-Type': ContentType.JSON
},
connectTimeout: Constants.HTTP_READ_TIMEOUT,
extraData: {}
});
let serverData: ResponseResult = new ResponseResult();
// Processes the data and returns.
return responseResult.then((value: http.HttpResponse) => {
if (value.responseCode === Constants.HTTP_CODE_200) {
// Obtains the returned data.
let result = `${value.result}`;
let resultJson: ResponseResult = JSON.parse(result);
if (resultJson.errorCode === Constants.SERVER_CODE_SUCCESS) {
serverData.data = resultJson.data;
}
serverData.errorCode = resultJson.errorCode;
serverData.errorMsg = resultJson.errorMsg;
} else {
serverData.errorMsg = `${$r('app.string.http_error_message')}&${value.responseCode}`;
}
return serverData;
}).catch(() => {
serverData.errorMsg = $r('app.string.http_error_message');
return serverData;
})
}
目前可以使用静态包下载后拷贝到项目中的方法来实现引入三方库。 首先在entry目录下新建一个文件夹,比如libs。将下载的har包复制进去。 然后打开entry目录下的oh-package.json5文件。在dependencies字段中填入引入的har包的地址。
完成之后进行一次sync操作。引入的三方静态包将会被以代码形式加入到项目中。
四. 最后总结
鸿蒙基础UI组件使用+页面跳转+网络数据请求+三方组件引入,这一套基础操作在着手去写App时是必不可少的。 熟练掌握后便可继续探索鸿蒙开发。刚开始还比较粗糙请多包涵!
为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
《鸿蒙 (Harmony OS)开发学习手册》
HarmonyOS 概念:https://qr21.cn/FV7h05
基于ArkTS 开发:https://qr21.cn/FV7h05
- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台任务(Background Task)管理
- 设备管理
- 设备使用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……
原文地址:https://blog.csdn.net/maniuT/article/details/134770378
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_36456.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!