WanAndroid(鸿蒙版)开发的第二篇

前言

DevEco Studio版本:4.0.0.600

WanAndroid的API链接:玩Android 开放API-玩Android - wanandroid.com

1、WanAndroid(鸿蒙版)开发的第一篇

其他一些参考点,请参考上面的WanAndroid开发第一篇

效果

首页实现

整体布局分为头部的Banner和底部的列表List,知道了整体的机构我们就来进行UI布局

1、Banner实现

参考华为官方  OpenHarmony Swiper

详细代码:

import router from '@ohos.router';
import { BannerItemBean } from '../bean/BannerItemBean';
import { HttpManager, RequestMethod } from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';
import { BannerBean } from '../bean/BannerBean';const TAG = 'Banner--- ';@Component
export struct Banner {@State bannerData: Array<BannerItemBean> = [];private swiperController: SwiperController = new SwiperController();@State isVisibility: boolean = trueprivate onDataFinish: () => void //数据加载完成回调aboutToAppear() {this.getBannerData()}private getBannerData() {HttpManager.getInstance().request<BannerBean>({method: RequestMethod.GET,header: { "Content-Type": "application/json" },url: 'https://www.wanandroid.com/banner/json', //wanAndroid的API:Banner}).then((result: BannerBean) => {LogUtils.info(TAG, "result: " + JSON.stringify(result))if (result.errorCode == 0) {this.isVisibility = truethis.bannerData = result.data} else {this.isVisibility = false}this.onDataFinish()}).catch((error) => {LogUtils.info(TAG, "error: " + JSON.stringify(error))this.isVisibility = falsethis.onDataFinish()})}build() {Swiper(this.swiperController) {ForEach(this.bannerData, (banner: BannerItemBean) => {Image(banner.imagePath).borderRadius(16).onClick(() => {router.pushUrl({url: 'pages/WebPage',params: {title: banner.title,uriLink: banner.url,isShowCollect: false,}}, router.RouterMode.Single)})}, (banner: BannerItemBean) => banner.url)}.margin({ top: 10 }).autoPlay(true).interval(1500).visibility(this.isVisibility ? Visibility.Visible : Visibility.None).width('100%').height(150)}
}

2、List列表实现

因为是带上拉加载和下拉刷新,参考我之前文章:鸿蒙自定义刷新组件使用_harmoneyos 自定义刷新

详细代码:

import {BaseResponseBean,Constants,HtmlUtils,HttpManager,RefreshController,RefreshListView,RequestMethod
} from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';
import { HomeListItemBean } from '../bean/HomeListItemBean';
import { HomeListBean } from '../bean/HomeListBean';
import router from '@ohos.router';
import promptAction from '@ohos.promptAction';const TAG = 'HomeList--- ';@Component
export struct HomeList {@State controller: RefreshController = new RefreshController()@State homeListData: Array<HomeListItemBean> = [];@State pageNum: number = 0@State isRefresh: boolean = trueprivate onDataFinish: () => void //数据加载完成回调@State userName: string = ''@State token_pass: string = ''@State listCollectState: Array<boolean> = [] //用于存储收藏状态aboutToAppear() {if (AppStorage.Has(Constants.APPSTORAGE_USERNAME)) {this.userName = AppStorage.Get(Constants.APPSTORAGE_USERNAME) as string}if (AppStorage.Has(Constants.APPSTORAGE_TOKEN_PASS)) {this.token_pass = AppStorage.Get(Constants.APPSTORAGE_TOKEN_PASS) as string}this.getHomeListData()}/*** 获取列表数据*/private getHomeListData() {HttpManager.getInstance().request<HomeListBean>({method: RequestMethod.GET,header: {"Content-Type": "application/json","Cookie": `loginUserName=${this.userName}; token_pass=${this.token_pass}`},url: `https://www.wanandroid.com/article/list/${this.pageNum}/json` //wanAndroid的API:Banner}).then((result: HomeListBean) => {LogUtils.info(TAG, "result: " + JSON.stringify(result))if (this.isRefresh) {this.controller.finishRefresh()} else {this.controller.finishLoadMore()}if (result.errorCode == 0) {if (this.isRefresh) {this.homeListData = result.data.datasfor (let i = 0; i < this.homeListData.length; i++) {this.listCollectState[i] = this.homeListData[i].collect}} else {this.homeListData = this.homeListData.concat(result.data.datas)}}this.onDataFinish()}).catch((error) => {LogUtils.info(TAG, "error: " + JSON.stringify(error))if (this.isRefresh) {this.controller.finishRefresh()} else {this.controller.finishLoadMore()}this.onDataFinish()})}@BuilderitemLayout(item: HomeListItemBean, index: number) {RelativeContainer() {//作者或分享人Text(item.author.length > 0 ? "作者:" + item.author : "分享人:" + item.shareUser).fontColor('#666666').fontSize(14).id("textAuthor").alignRules({top: { anchor: '__container__', align: VerticalAlign.Top },left: { anchor: '__container__', align: HorizontalAlign.Start }})Text(item.superChapterName + '/' + item.chapterName).fontColor('#1296db').fontSize(14).id("textChapterName").alignRules({top: { anchor: '__container__', align: VerticalAlign.Top },right: { anchor: '__container__', align: HorizontalAlign.End }})//标题Text(HtmlUtils.formatStr(item.title)).fontColor('#333333').fontWeight(FontWeight.Bold).maxLines(2).textOverflow({overflow: TextOverflow.Ellipsis}).fontSize(20).margin({ top: 10 }).id("textTitle").alignRules({top: { anchor: 'textAuthor', align: VerticalAlign.Bottom },left: { anchor: '__container__', align: HorizontalAlign.Start }})//更新时间Text("时间:" + item.niceDate).fontColor('#666666').fontSize(14).id("textNiceDate").alignRules({bottom: { anchor: '__container__', align: VerticalAlign.Bottom },left: { anchor: '__container__', align: HorizontalAlign.Start }})//收藏状态Image(this.listCollectState[index] ? $r('app.media.ic_select_collect') : $r('app.media.ic_normal_collect')).width(26).height(26).id('imageCollect').alignRules({bottom: { anchor: '__container__', align: VerticalAlign.Bottom },right: { anchor: '__container__', align: HorizontalAlign.End }}).onClick(() => {this.setCollectData(item.id, index)})}.width('100%').height(120).padding(10).margin({ left: 10, right: 10, top: 6, bottom: 6 }).borderRadius(10).backgroundColor(Color.White)}build() {RefreshListView({list: this.homeListData,controller: this.controller,isEnableLog: true,refreshLayout: (item: HomeListItemBean, index: number): void => this.itemLayout(item, index),onItemClick: (item: HomeListItemBean, index: number) => {LogUtils.info(TAG, "点击了:index: " + index + " item: " + item)router.pushUrl({url: 'pages/WebPage',params: {title: item.title,uriLink: item.link,isShowCollect: true,isCollect: this.listCollectState[index]}}, router.RouterMode.Single)},onRefresh: () => {//下拉刷新this.isRefresh = truethis.pageNum = 0this.getHomeListData()},onLoadMore: () => {//上拉加载this.isRefresh = falsethis.pageNum++this.getHomeListData()}})}/*** 设置收藏和取消收藏状态* @param id  文章id* @param index  数据角标*/private setCollectData(id: number, index: number) {let collect = this.listCollectState[index]let urlLink = collect ? `https://www.wanandroid.com/lg/uncollect_originId/${id}/json` : `https://www.wanandroid.com/lg/collect/${id}/json` //取消收藏和收藏接口HttpManager.getInstance().request<BaseResponseBean>({method: RequestMethod.POST,header: {"Content-Type": "application/json","Cookie": `loginUserName=${this.userName}; token_pass=${this.token_pass}`},url: urlLink //wanAndroid的API:收藏和取消收藏}).then((result: BaseResponseBean) => {LogUtils.info(TAG, "收藏  result: " + JSON.stringify(result))if (result.errorCode == 0) {this.listCollectState[index] = !this.listCollectState[index]promptAction.showToast({ message: collect ? "取消收藏成功" : "收藏成功" })} else {promptAction.showToast({ message: result.errorMsg })}}).catch((error) => {LogUtils.info(TAG, "收藏  error: " + JSON.stringify(error))})}
}

注意点:就是在获取List数据时,通过WanAndroid的API知道要想获取收藏状态需要传入用户登录时的Cookie,但是鸿蒙没有像Android那样的Cookie处理,只能通过在登录的时候获取loginUserName和token_pass然后在请求时将这两个参数添加到请求头中,实现如下图:

这两个参数获取参考第一篇的文章。

3、将两个视图整合

详细代码:

import { Banner } from './widget/Banner';
import { HomeList } from './widget/HomeList';
import { LoadingDialog } from '@app/BaseLibrary';
import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';@Component
export struct HomePage {@State bannerLoadDataStatus: boolean = false@State HomeListLoadDataStatus: boolean = falseaboutToAppear() {//弹窗控制器,显示this.dialogController.open()}private dialogController = new CustomDialogController({builder: LoadingDialog(),customStyle: true,alignment: DialogAlignment.Center, // 可设置dialog的对齐方式,设定显示在底部或中间等,默认为底部显示})build() {Column() {Banner({ onDataFinish: () => {this.bannerLoadDataStatus = trueLogUtils.info("33333333333 Banner  bannerLoadDataStatus: " + this.bannerLoadDataStatus + "  HomeListLoadDataStatus: " + this.HomeListLoadDataStatus)if (this.bannerLoadDataStatus && this.HomeListLoadDataStatus) {this.dialogController.close()}} })HomeList({ onDataFinish: () => {this.HomeListLoadDataStatus = trueLogUtils.info("33333333333 HomeList  bannerLoadDataStatus: " + this.bannerLoadDataStatus + "  HomeListLoadDataStatus: " + this.HomeListLoadDataStatus)if (this.bannerLoadDataStatus && this.HomeListLoadDataStatus) {this.dialogController.close()}} }).flexShrink(1).margin({ top: 10 })}.visibility(this.bannerLoadDataStatus && this.HomeListLoadDataStatus ? Visibility.Visible : Visibility.Hidden).width('100%').height('100%')}
}

源代码地址:WanAndroid_Harmony: WanAndroid的鸿蒙版本

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/741146.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序内嵌web-view实现路由切换到同级页面无效的解决方案

如果与当web-view不处于同一层级目录下&#xff0c;直接使用 uni.navigateTo({url:‘xxxx’});即可实现跳转&#xff0c;如果处于同级目录下需要使用 uni.switchTab({url:‘xxxx’}),并且声明url时候需要注意是…/的形式&#xff0c;比如web-view在pages/chat/index.vue ,跳转到…

Android 9.0 关于在系统Launcher3中调用截图api总是返回null的解决方案

1.概述 在9.0的系统rom产品定制化开发中,在Launcher3的开发中,在某些时候需要调用截图接口来进行截屏功能实现,而在Launcher3中发现调用系统截屏接口SurfaceControl.screenshot进行截图的时候始终为null, 获取不到系统当前页面的截屏功能,所以需要找到当前截屏失败的原因然…

java 与 C#(.net) AES加密对接

java方的代码&#xff1a; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64;public class AESEncryptionExample {private static final String ALGORITHM "AES"; // 指定加密…

Linux运维总结:Centos7.6之OpenSSH7.4升级版本至9.3

一、环境信息 操作系统&#xff1a;Centos7.6.1810 OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 注意&#xff1a;升级后由于加密算法的区别&#xff0c;低版本的SSH工具可能无法连接&#xff0c;建议改用Xshell7或SecureCRT9.0以上版本。 二、注意事项 1、 检查防火墙或selinux是否…

基于Gui Guider进行LVGL的页面绘制和移植

在之前的文章里讲过一种页面切换的方式&#xff0c;那就是&#xff1a;定义和创建页面对象绘制页面内容切换页面。参考这篇文章&#xff1a; LVGL如何创建页面并实现页面的切换-CSDN博客 这篇文章讲了如何绘制并切换页面。 但是现在遇到一个问题&#xff0c;那就是页面绘制&…

每日leetcode--接雨水

引言 接雨水问题是一个经典的算法问题&#xff0c;它要求我们计算给定一组不同高度的墙壁时&#xff0c;这些墙壁之间能够蓄积多少雨水。解决这个问题的方法有很多&#xff0c;其中一种常见的解法是通过辅助数组来记录每个位置的左右最大高度&#xff0c;并计算每个位置上方能…

代码学习记录17

随想录日记part17 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.12 主要内容&#xff1a;今天的主要内容是二叉树的第六部分&#xff0c;主要涉及二叉搜索树的最小绝对差 &#xff1b;二叉搜索树中的众数&#xff1b;二叉树的最近公共祖先。 530.二叉搜索树…

openGauss使用BenchmarkSQL进行性能测试(上)

一、前言 本文提供openGauss使用BenchmarkSQL进行性能测试的方法和测试数据报告。 BenchmarkSQL&#xff0c;一个JDBC基准测试工具&#xff0c;内嵌了TPC-C测试脚本&#xff0c;支持很多数据库&#xff0c;如PostgreSQL、Oracle和Mysql等。 TPC-C是专门针对联机交易处理系统…

【QT】文件流操作(QTextStream/QDataStream)

文本流/数据流&#xff08;二级制格式&#xff09; 文本流 &#xff08;依赖平台&#xff0c;不同平台可能乱码&#xff09;涉及文件编码 #include <QTextStream>操作的都是基础数据类型&#xff1a;int float string //Image Qpoint QRect就不可以操作 需要下面的 …

【Python】新手入门学习:详细介绍接口分隔原则(ISP)及其作用、代码示例

【Python】新手入门学习&#xff1a;详细介绍接口分隔原则&#xff08;ISP&#xff09;及其作用、代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、Py…

基于Qt 和python 的自动升级功能

需求&#xff1a; 公司内部的一个客户端工具&#xff0c;想加上一个自动升级功能。 服务端&#xff1a; 1&#xff0c;服务端使用python3.7 &#xff0c;搭配 fastapi 和uvicorn 写一个简单的服务&#xff0c;开出一个get接口&#xff0c;用于客户端读取安装包的版本&#…

<机器学习初识>——《机器学习》

目录 一、人工智能概述 1 人工智能应用场景 2 人工智能发展必备三要素 3 人工智能、机器学习和深度学习 二、人工智能发展历程 1 人工智能的起源 1.1 图灵测试 1.2 达特茅斯会议 2 发展历程 三、 人工智能主要分支 1 主要分支介绍 1.1 分支一&#xff1a;计算机视觉…

linux 启动命令

添加权限 drwxr-xr-x -rwxr-xr-x <strong>第一位&#xff1a;-代表文件&#xff0c;d代表目录<br> 用户、组用户、其他用户都是rwx形式&#xff0c;其中r表示读、w表示写、x表示可执行&#xff0c;-表示没有权限&#xff0c;拿用户组举例&#xff0c;r只能出…

c++中string的模拟实现(超详细!!!)

1.string的成员变量、&#xff08;拷贝&#xff09;构造、析构函数 1.1.成员变量 private:char* _str;size_t _size; //string中有效字符个数size_t _capacity; //string中能存储有效字符个数的大小 1.2&#xff08;拷贝&#xff09;构造函数 //构造函数string(const char* …

【Linux进阶之路】HTTP协议

文章目录 一、基本概念1.HTTP2.域名3.默认端口号4.URL 二、请求与响应1.抓包工具2.基本框架3.简易实现3.1 HttpServer3.2 HttpRequest3.2.1 version13.2.2 version23.2.3 version3 总结尾序 一、基本概念 常见的应用层协议&#xff1a; HTTPS (HyperText Transfer Protocol Sec…

C# 8.0+版本项目 string不可为空

1.在某一次新建项目的时候发现&#xff0c;新建的项目&#xff0c;写的测试接口&#xff0c;接口的入参有string的参数&#xff0c; 但是调用接口的时候string的参数没有传报了400&#xff0c;很奇怪&#xff0c;也没有语法错误之类的。 2.解决办法 在项目上右键->属性->…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Span)

作为Text组件的子组件&#xff0c;用于显示行内文本的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 该组件从API Version 10开始支持继承父组件Text的属性&#xff0c;即如果子组件未设置…

单片机开发-实现Zigbee的LED灯交替闪烁

前言 前提须知&#xff1a; 1.本文所讲的单片机开发的代码&#xff0c;使用软件是IAR Embedded Workbench&#xff1b; 2.本文所讲的内容与全国职业院校技能大赛“物联网应用开发”赛项Zigbee模块题目类似&#xff1b; 3.单片机Zigbee内容以收入到我的专栏“单片机Zigbee当…

C# 数据结构初始化长度

在C#中&#xff0c;各个数据结构的初始化长度是动态的&#xff0c;下面是一个例子&#xff0c;展示了如何初始化各个数据结构并演示它们的长度&#xff1a; using System; using System.Collections.Generic;class Program {static void Main(){// 初始化数组int[] intArray …

直播美颜SDK的商业化应用:如何为直播平台带来更多商业机会?

直播过程中的自然环境和摄像头本身的限制可能会影响用户的体验&#xff0c;因此直播美颜SDK的商业化应用应运而生&#xff0c;它为直播平台带来了更多商业机会。 直播美颜SDK是一种集成在直播平台中的软件开发工具包&#xff0c;它能够对直播过程中的视频流进行实时的美颜处理…