HarmonyOS NEXT 应用开发实战(四、仿知乎日报的首页轮播图实现)

news2024/11/25 10:50:56

在本篇博文中,我们将探讨如何在HarmonyOS NEXT应用中实现一个仿知乎日报的首页轮播图效果。我们将使用Swiper组件来展示轮播图,并且在轮播图下方添加半透明背景的标题。以下是具体的实现步骤和代码示例。

1. 项目结构与数据源

首先,我们需要从API获取轮播图的数据,此处我们模拟一个数据源类MySwiperData来存储和管理轮播图数据。

import { getSwiperList} from "../../common/api/home"
import { BaseResponse, ErrorResp } from '../../common/bean/ApiTypes';
import { Log } from '../../utils/logutil'

class MySwiperData implements IDataSource {
  private list: number[] = []

  constructor(list: number[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): number {
    return this.list[index]
  }

  registerDataChangeListener(listener: DataChangeListener): void {}
  unregisterDataChangeListener() {}
}

2. 组件实现

接下来,我们定义一个名为ZhiHu的组件,在这个组件中我们将实现轮播图效果及标题展示。

2.1 组件生命周期

我们重写了aboutToAppearaboutToDisappear这两个生命周期方法,以在组件出现和消失时进行相应的日志记录和数据请求:

@Component
export default struct ZhiHu {
  @State message: string = 'Hello World';
  private swiperController: SwiperController = new SwiperController()
  private data: MySwiperData = new MySwiperData([])

  aboutToAppear() {
    Log.info('ZhiHu aboutToAppear');
    getSwiperList().then((res) => {
      // 模拟处理API返回的数据
      Log.debug(res.data.message);
      // 进一步的逻辑处理
      let list: number[] = [];
      for (let i = 1; i <= 10; i++) {
        list.push(i);
      }
      this.data = new MySwiperData(list);
    }).catch((err: BaseResponse<ErrorResp>) => {
      Log.debug("request", "error", err.data.message);
    });
  }

  aboutToDisappear() {
    Log.info('ZhiHu aboutToDisappear');
  }

2.2 构建界面

build方法中,我们构造轮播图和标题栏的UI。这里的核心是使用Swiper组件来实现轮播图,搭配使用ColumnStack组件来组织布局。Stack组件的作用是用来实现让标题堆叠显示在轮播图的上面,并实现半透明的效果。

build() {
  Row() {
    Column({ space: 0 }) {
      // 标题栏
      Text("日报")
        .size({ width: '100%', height: 50 })
        .backgroundColor("#28bff1")
        .fontColor("#ffffff")
        .textAlign(TextAlign.Center)
        .fontSize("18fp");

      // 内容项
      Stack({ alignContent: Alignment.Center }) {
        Swiper(this.swiperController) {
          LazyForEach(this.data, (item: string) => {
            Text(item.toString())
              .width('100%')
              .height(160)
              .backgroundColor(0xAFEEEE)
              .textAlign(TextAlign.Center)
              .fontSize(30);
          }, (item: string) => item);
        }
        .cachedCount(2)
        .index(1)
        .autoPlay(true)
        .interval(4000)
        .loop(true)
        .indicatorInteractive(true)
        .duration(1000)
        .itemSpace(0)
        .curve(Curve.Linear)
        .onChange((index: number) => { console.info(index.toString()) })
        .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => { 
          console.info("index: " + index); 
        })
        .zIndex(1);

        // 标题展示
        Text("标题")
          .margin({ top: 80 })
          .width('100%').height(50)
          .textAlign(TextAlign.Center)
          .fontSize(20)
          .fontColor(Color.White)
          .opacity(100) // 完全不透明
          .backgroundColor('#808080AA') // 半透明背景
          .zIndex(2);

      }.height(160);

    }.size({ width: '100%', height: '100%' });
  }
}

注意上面的zIndex属性的作用,谁大谁显示在最上层。 

2.3 重要布局细节

在上面的代码中,我们特别注意了以下几点:

  • 使用了Stack组件来重叠显示轮播图和标题,这样可以方便地将标题放置在轮播图上方。
  • 通过设置标题的opacitybackgroundColor属性,使得标题栏呈现出半透明的效果,增强了视觉美感和可读性。
  • Swiper的自动播放、轮播间隔以及用户交互等功能都进行了详细设置,以提供良好的用户体验。

3. 完整代码

import {getSwiperList} from "../../common/api/home"
import { BaseResponse,ErrorResp } from '../../common/bean/ApiTypes';
import { Log } from '../../utils/logutil'

class MySwiperData implements IDataSource {
  private list: number[] = []

  constructor(list: number[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): number {
    return this.list[index]
  }

  registerDataChangeListener(listener: DataChangeListener): void {
  }

  unregisterDataChangeListener() {
  }
}

@Component
export default struct ZhiHu{
  @State message: string = 'Hello World';
  private swiperController: SwiperController = new SwiperController()
  private data: MySwiperData = new MySwiperData([])

  // 组件生命周期
  aboutToAppear() {
    Log.info('ZhiHu aboutToAppear');
    getSwiperList().then((res) => {
      Log.debug(res.data.message)
      Log.debug("request","res.data.code:%{public}d",res.data.code)
      Log.debug("request","res.data.data[0]:%{public}s",res.data.data[0].id)
      Log.debug("request","res.data.data[0]:%{public}s",res.data.data[0].imageUrl)
      Log.debug("request","res.data.data[0]:%{public}s",res.data.data[0].title)
    }).catch((err:BaseResponse<ErrorResp>) => {
      Log.debug("request","err.data.code:%d",err.data.code)
      Log.debug("request",err.data.message)
    });
    let list: number[] = []
    for (let i = 1; i <= 10; i++) {
      list.push(i);
    }
    this.data = new MySwiperData(list)
  }

  // 组件生命周期
  aboutToDisappear() {
    Log.info('ZhiHu aboutToDisappear');
  }

  build() {
    Row() {
      Column({ space: 0 }) {
        // 标题栏
        Text("日报")
          .size({ width: '100%', height: 50 })
          .backgroundColor("#28bff1")
          .fontColor("#ffffff")
          .textAlign(TextAlign.Center)
          .fontSize("18fp")

        // 内容项
        Stack({ alignContent: Alignment.Center }) {
          Swiper(this.swiperController) {
            LazyForEach(this.data, (item: string) => {
              Text(item.toString())
                .width('100%')
                .height(160)
                .backgroundColor(0xAFEEEE)
                .textAlign(TextAlign.Center)
                .fontSize(30)
            }, (item: string) => item)
          }
          .cachedCount(2)
          .index(1)
          .autoPlay(true)
          .interval(4000)
          .loop(true)
          .indicatorInteractive(true)
          .duration(1000)
          .itemSpace(0)
          .curve(Curve.Linear)
          .onChange((index: number) => {
            console.info(index.toString())
          })
          .onGestureSwipe((index: number, extraInfo: SwiperAnimationEvent) => {
            console.info("index: " + index)
            console.info("current offset: " + extraInfo.currentOffset)
          })
          .zIndex(1)

          // 显示轮播图标题
          Text("标题aaaaaaaaaaaaaaaaaa啊啊啊啊啊啊啊啊")
            .padding(5)
            .margin({ top:60 })
            .width('100%').height(50)
            .textAlign(TextAlign.Center)
            .maxLines(2)
            .textOverflow({overflow:TextOverflow.Clip})
            .fontSize(20)
            .fontColor(Color.White)
            .opacity(100) // 设置标题的透明度 不透明度设为100%,表示完全不透明
            .backgroundColor('#808080AA') // 背景颜色设为透明
            .zIndex(2)

        }.height(160) // 设置标题的高度

      }.size({ width: '100%', height: '100%' })
    }
  }
}

4. 总结

通过以上实现,我们成功模仿了知乎日报的轮播图效果。使用HarmonyOS NEXT提供的组件和API,我们能够快速构建出功能丰富且具有用户友好的界面。接下来,您可以在这个基础上进行更多的功能扩展与视觉设计,提高应用的吸引力与易用性。希望本篇博文对您在HarmonyOS NEXT的开发有所帮助!

示例项目代码地址:zhihudaily: HarmonyOS NEXT 项目开发实战,仿知乎日报的实现

写在最后

最后,推荐下笔者的业余开源app影视项目“爱影家”,推荐分享给与我一样喜欢免费观影的朋友。【注:该项目仅限于学习研究使用!请勿用于其他用途!】

开源地址:爱影家app开源项目介绍及源码

https://gitee.com/yyz116/imovie

其他资源

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-container-swiper-V5

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

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

相关文章

Django兴农购物网站系统—计算机毕业设计源码38256

摘 要 助农工作是当前我国全面建成小康社会的重点工作&#xff0c;由于我国农村地域广大&#xff0c;贫困人口多&#xff0c;区域差异大&#xff0c;因此&#xff0c;不同区域的扶贫方法也是不一样的。近年来&#xff0c;随着网络的普及。许多农村地区物产丰富&#xff0c;但由…

计组_中断响应的步骤

2024.10.13&#xff1a;计算机组成原理学习笔记 中断响应步骤 中断响应 &#xff08;中断响应的过程也称中断隐指令&#xff09;第一步&#xff1a;关中断第二步&#xff1a;保存断点第三步&#xff1a;引出中断服务程序中断源识别判优方法1&#xff1a;软件查询方法中断源识别…

Redis两种持久化方式

目录 一、Redis持久化 RDB 四种执行场景 底层执行原理 优缺点 AOP 三种fsync策略 AOF重写机制 工作基本流程 优缺点 RDB和AOF的对比 混合持久化 Redis 持久化的主要目的是为了确保数据的持久性和可靠性&#xff0c;避免因意外崩溃或重启导致的数据丢失。以下是一些进…

基于STM32的图形识别智能跟踪小车设计

引言 本项目设计了一个基于STM32的图形识别智能跟踪小车&#xff0c;能够通过摄像头识别特定图形或标志&#xff0c;并自动跟随这些图形进行移动。系统结合了摄像头模块和图像处理算法&#xff0c;实现了对前方物体的识别与跟踪。同时&#xff0c;小车具备避障功能&#xff0c…

顺序表|消失的数字|轮转数组|移除元素|合并有序数组|删除有序数组中重复项(C)

面试题 17.04. 消失的数字 思路一 排序遍历 如果下一个不等于上一个数1&#xff0c;这个下一个数就是消失的数字 时间复杂度 O ( N ⋅ log ⁡ 2 N ) O(N\cdot \log_{2}N) O(N⋅log2​N) 思路二 0N等差数列公式计算结果 - 数组中的值&#xff0c;结果就是消失的数字 int mis…

基于海市蜃楼算法(Fata Morgana Algorithm ,FATA)的多无人机协同三维路径规划(提供MATLAB代码)

一、海市蜃楼算法 海市蜃楼算法&#xff08;Fata Morgana Algorithm &#xff0c;FATA&#xff09;是2024年提出一种新型的群体智能优化算法&#xff0c;它的设计灵感来源于自然现象中的海市蜃楼形成过程。FATA算法通过模仿光线在不均匀介质中的传播方式&#xff0c;提出了两种…

日语学习者福音:4大翻译软件集锦,总有一款适合你!

现在全球化了&#xff0c;学个外语&#xff0c;尤其是日语这种很有魅力的语言&#xff0c;成了很多人的愿望。不管是为了方便旅行&#xff0c;还是喜欢日本文化&#xff0c;或者想在工作中更有竞争力&#xff0c;学日语都挺重要的。学语言不容易&#xff0c;特别是遇到难懂的句…

C#实现Punycode编码/解码

测试代码 string word "我爱你"; string idn "我爱你.中国"; string wordCode PunyCode.Encode(word); string punycode PunyCode.IDN2Punycode(idn);Console.WriteLine(word); Console.WriteLine(wordCode); Console.WriteLine(PunyCode.Decode(word…

【工欲善其事】巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号

文章目录 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号1 问题描述2 解决方案3 具体步骤4 效果测试5 小结与复盘 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号 1 问题描述 不知各位是否也为复制过来的文本中夹杂的回车换行符抓狂过&#xff1f;就是在复…

Spring Boot知识管理:提升信息检索效率

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

ubuntu下route命令详解

buntu下route命令详解 1、显示路由表 route -n2、临时路由设置&#xff0c;重启网卡失效#添加一条路由(发往192.168.62这个网段的全部要经过网关192.168.1.1)route add -net 192.168.62.0 netmask 255.255.255.0 gw 192.168.1.1#删除一条路由 删除的时候不用写网关route del …

extern “C“ 的作用、C++ 和 C 编译的不同、C++ 编译过程的五个主要阶段

在 C 中&#xff0c;如果需要从 C 语言导入函数或与 C 代码交互&#xff0c;需要使用 extern "C" 关键字。这是因为 C 和 C 在编译过程中的 符号命名机制&#xff08;即 "名称修饰" 或 "name mangling"&#xff09;不同。 1. extern "C&qu…

怎么把一段音频的人声和背景音乐分开?

在数字音频处理中&#xff0c;将一段音频中的人声和背景音乐分开是一个复杂但又常见的需求。这种技术广泛应用于音乐制作、影视后期、广告制作等多个领域。本文将为你详细解析如何通过不同的方法实现这一目标&#xff0c;帮助你更好地掌握音频分离技术。 一、音频分离的基本概念…

无人直播自动化回复客户咨询

我们插件是根据页面元素变动进行自动化操作的&#xff0c;想要实现网页版自动化&#xff0c;必须了解html以及dom结构&#xff0c;还有xpath定位方法。 各大直播后台页面结构不一样&#xff0c;所以要进行兼容处理&#xff0c;我们一个插件支持以下直播或客服平台 唯一客服浏…

数据结构与算法:栈与队列的高级应用

目录 3.1 栈的高级用法 3.2 队列的深度应用 3.3 栈与队列的综合应用 总结 数据结构与算法&#xff1a;栈与队列的高级应用 栈和队列是两种重要的线性数据结构&#xff0c;它们在计算机科学和工程的许多领域都有广泛的应用。从函数调用到表达式求值&#xff0c;再到任务调度…

c#的opcua客户端源码,支持用户名密码

在工作中遇到需要采集西门子机床的opcua和kepServer的opcua&#xff0c;找了一些网上的demo都不能都连接成功&#xff0c;好不容易找到一个两个都支持的c#opcua客户端源码&#xff0c;分享给大家。 软件界面如下 连接kepserver成功的界面 连接西门子opcua的界面 c#源码链接如下…

开关电源调制模式和工作模式

开关电源调制模式和工作模式 ‌‌开关电源定义开关电源分类‌单管DC/DC和、双管DC/DC和四管DC/DC的主要区别正激和反激 DCDCBUCK原理BOOST原理BUCK-BOOST原理异步整流和异步整流同步整流异步整流同步和异步整流区别同步和异步整流优缺点 DCDC调制模式PWM&#xff08;Pulse Widt…

C++ | Leetcode C++题解之第475题供暖器

题目&#xff1a; 题解&#xff1a; class Solution { public:int findRadius(vector<int>& houses, vector<int>& heaters) {sort(houses.begin(), houses.end());sort(heaters.begin(), heaters.end());int ans 0;for (int i 0, j 0; i < houses.…

轻松掌握TCP与UDP核心机制

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:网络编程TCP&#x1f649; &#x1f439;今日诗词:Best wishes&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收…

相机曝光的两种模式

相机的曝光模式 相机帧率和曝光时间的关系 相机的图像采集包括曝光(Exposure)和读出(Readout)两部分 曝光又分为非重叠(non-overlapped)曝光和重叠(overlapped)曝光两种 在非重叠(“non-overlapped”)模式中&#xff0c;每个图像采集的周期中&#xff0c;相机在下一个图像采集…