找回密码
 立即注册
首页 业界区 安全 HarmonyOS Next 开发一款简单应用练练手

HarmonyOS Next 开发一款简单应用练练手

苗嘉惠 2025-6-1 21:19:44
基于ArkUI开发的一款鸿蒙OS应用,调用开放API玩android,实现了简单的页面导航,登录,登录状态保存,数据展示,h5页面加载等功能.
1.png

2.png

3.png

首页底部导航栏

使用Tabs实现底部导航,Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar。TabContent是内容页,TabBar是导航页签栏。每一个TabContent对应的内容需要有一个页签,可以通过TabContent的tabBar属性进行配置。
  1. Tabs({ barPosition: BarPosition.End }) {
  2.   TabContent() {
  3.     HomeComponent()
  4.   }.align(Alignment.Top)
  5.   .tabBar(this.tabBuilder("首页", 0, $r("app.media.main_index_select_icon"), $r("app.media.main_index_icon")))
  6.   TabContent() {
  7.     SystemComponent()
  8.   }.align(Alignment.Top)
  9.   .tabBar(this.tabBuilder("体系", 1, $r("app.media.main_house_select_icon"), $r("app.media.main_house_icon")))
  10.   TabContent() {
  11.     ProjectComponent()
  12.   }.tabBar(this.tabBuilder("项目", 2, $r("app.media.main_message_select_icon"), $r("app.media.main_message_icon")))
  13.   TabContent() {
  14.     MyComponent()
  15.   }.align(Alignment.Top)
  16.   .tabBar(this.tabBuilder("我的", 3, $r("app.media.main_me_select_icon"), $r("app.media.main_me_icon")))
  17. }.scrollable(false)
  18. .divider({ strokeWidth: 0.3 })
  19. .animationDuration(0)
  20. .onChange((index) => {
  21.   this.currentIndex = index
  22. })
复制代码
barPosition控制导航栏位置,BarPosition.Start表示顶部导航栏和BarPosition.End表示低部导航栏;
divider可以定义导航栏分割线样式;animationDuration设置导航页main切换动画时长;onChange导航页面切换监听。
HomeComponent,SystemComponent,ProjectComponent,MyComponent分别是自定义的4个页面组件。切换导航可以切换到对应的页面。
主页自定义组件(HomeComponent)

主页HomeComponent由轮播图Swiper组件和列表组件组成,用来显示文章列表,外面嵌套了一个下拉刷新组件PullToRefresh,大概结构是这样的
  1. 下拉刷新/上拉加载
  2. PullToRefresh({
  3.   data: this.articleList,
  4.   scroller: this.scroller,
  5.   onRefresh: () => {
  6.     //刷新执行回调
  7.   },
  8.   onLoadMore: () => {
  9.    //加载更多执行回调
  10.   },
  11.   customList: () => {
  12.    //刷新页面内容
  13.     Scroll(this.scroller) {
  14.        Column(){
  15.           //轮播图
  16.           Swiper(){}
  17.           //文章列表
  18.           ForEach(this.articleList, (item: ArticleData) => {
  19.              ArticleListItem({ article: item })
  20.           })
  21.        }
  22.     }
  23. })
复制代码
刷新组件使用的三方库@ohos/pulltorefresh,刷新组件子组件必须是滑动组件,这里由于页面由轮播图和列表组件,所以在外层嵌套了一个Scroll组件,保证页面运行正常,SystemComponent是一个自定义组件内构造函数@Builder,可以将重复使用的UI元素抽象成⼀个方法,这里用来展示列表每项布局。
Tips:Scroll组件和PullToRefresh需要共用一个控制器Scroller。
体系自定义组件(SystemComponent)

体系页面由顶部Tabs嵌套Grid和下拉刷新pulltorefresh列表组成,Grid组件是系统提供的用来展示宫格的组件,
页面结构如下:
  1. //顶部导航栏
  2. Tabs({ barPosition: BarPosition.Start }){
  3.   TabContent(){
  4.     Column(){
  5.     //顶部宫格组件
  6.       Grid(){}
  7.       //下拉刷新组件
  8.       PullToRefresh({
  9.         customList: () => {
  10.         //滑动组件
  11.           Scroll(){
  12.             Column(){
  13.             //文章列表item项
  14.               ArticleListItem()
  15.             }
  16.           }
  17.         }
  18.       })
  19.     }
  20.   }
  21. }
复制代码
此页面导航栏下方嵌套宫格组件,宫格组件下方使用下拉刷新组件嵌套列表展示。切换导航,调用接口刷新宫格和列表数据,选择宫格组件页会刷新列表数据。
项目自定义组件(ProjectComponent)

项目页面由Tabs直接嵌套下拉刷新组件,下拉刷新组件嵌套Grid宫格组件组成,页面结构如下:
  1. //顶部导航栏
  2. Tabs({ barPosition: BarPosition.Start }){
  3.    TabContent(){
  4.      //下拉刷新组件
  5.       PullToRefresh({
  6.         customList: () => {
  7.            Grid(this.scroller) {
  8.              ForEach(this.projectList, (item: ArticleData) => {
  9.                GridItem() {
  10.                  //宫格item样式
  11.                }
  12.              })
  13.            }
  14.            .columnsTemplate("1fr 1fr")
  15.            .width("95%")
  16.            .columnsGap(10)
  17.            .scrollBar(BarState.Off)
  18.            .padding(1)
  19.         }
  20.       })
  21.    }
  22. }
复制代码
columnsTemplate方法可以设置宫格的列数,一个1fr代表1列,columnsGap设置列表间距,scrollBar设置进度条样式。
网络请求@ohos/axios

网络请求使用了@ohos/axios三方库,简单封装了下:
  1. export class HttpUtils {
  2.   private static instance: HttpUtils = new HttpUtils()
  3.   private axiosInstance: AxiosInstance
  4.   private constructor() {
  5.     this.axiosInstance = axios.create({
  6.       baseURL: 'https://www.wanandroid.com/',
  7.       timeout: 10 * 1000,
  8.       //设置全局请求头
  9.       headers: { "Content-Type": "application/x-www-form-urlencoded" },
  10.       //设置代理
  11.       // proxy: { host: "192.168.10.229", port: 8888, exclusionList: [] }
  12.     });
  13.    
  14.     //拦截请求数据处理一些业务逻辑,比如添加cookie到请求中
  15.     this.axiosInstance.interceptors.request.use(async (config: InternalAxiosRequestConfig) => {
  16.       if (config.url != WanAndroidUrl.Login) {
  17.         //如果不是登录接口,则需要添加cookie到请求头中
  18.         const cookies = await PFUtils.get<string>("cookies").then()
  19.         config.headers["Cookie"] = cookies
  20.       }
  21.       console.log("请求数据:", JSON.stringify(config.headers))
  22.       return config;
  23.     });
  24.    
  25.     //拦截响应数据,处理一些业务逻辑,比如cookie保存
  26.     this.axiosInstance.interceptors.response.use((response: AxiosResponse) => {
  27.       console.log("响应数据:", response.config.url)
  28.       console.log("响应数据:", JSON.stringify(response.data))
  29.       if (response.config.url == WanAndroidUrl.Login) {
  30.         //如果是登录接口,则需要你保存cookie
  31.         const cookies = response.headers["set-cookie"] as string[]
  32.         //保存cookie到缓存中
  33.         PFUtils.put<string>("cookies", cookies.toString())
  34.         //保存登录状态
  35.         PFUtils.put<boolean>("LoginState", true)
  36.         //通知其他页面用户登录成功
  37.         emitter.emit({ eventId: Constant.USER_LOGIN })
  38.       }
  39.       return response;
  40.     }, (error: AxiosError) => {
  41.       // 对响应错误做点什么
  42.       console.log("请求错误数据:", JSON.stringify(error))
  43.     });
  44.   }
  45. }
复制代码
项目地址:鸿蒙版玩Android

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册