OpenHarmony实战开发-滑动容器组件Swiper的使用

介绍

本篇Codelab主要介绍了滑动容器组件Swiper的几种常见的应用场景,包括顶部导航、轮播图以及视频滑动播放。

相关概念

  • Swiper:滑动容器,提供子组件切换滑动的能力。
  • Stack:堆叠容器,子组件按照顺序依次入栈,后入栈组件在先入栈组件上方显示。
  • Video:视频播放组件。
  • Observed和ObjectLink数据管理:@Observed应用于类,表示该类中的数据变更被UI页面管理,例如:@Observed class ClassA {}。@ObjectLink应用于被@Observed所装饰类的对象,例如:@ObjectLink a: ClassA。

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

  • 开发板类型:润和RK3568开发板。
  • OpenHarmony系统:3.2 Release。

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

2.搭建烧录环境。

  1. 完成DevEco Device Tool的安装
  2. 完成RK3568开发板的烧录

3.搭建开发环境。

  1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
  2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
  3. 工程创建完成后,选择使用真机进行调测。

代码结构解读

本篇Codelab只对核心代码进行讲解。

├──entry/src/main/ets                 // 代码区
│  ├──common                          
│  │  └──constants                    
│  │     ├──CommonConstant.ets        // 公共常量 
│  │     ├──PictureConstants.ets      // 图片所使用的常量
│  │     ├──TopBarConstants.ets       // TopBar使用的常量
│  │     └──VideoConstants.ets        // Video使用的常量                       
│  ├──entryability                      
│  │  └──EntryAbility.ts              // 程序入口类                          
│  ├──pages                            
│  │  ├──PageVideo.ets                // 视频播放页
│  │  └──SwiperIndex.ets              // 应用首页                          
│  ├──view                             
│  │  ├──all                          
│  │  │  └──PictureSort.ets           // “全部”tab页图片类别组件                           
│  │  ├──common                        
│  │  │  ├──Banner.ets                // 轮播图组件
│  │  │  ├──PictureView.ets           // 图片组件
│  │  │  └──TopBar.ets                // 顶部导航组件                           
│  │  ├──movie                         
│  │  │  └──MovieSort.ets             // “电影”tab页图片类别组件                        
│  │  ├──play                         // 视频播放组件目录 
│  │  │  ├──CommentView.ets           // 评论模块组件
│  │  │  ├──DescriptionView.ets       // 视频描述信息组件
│  │  │  ├──NavigationView.ets        // 顶部返回导航组件
│  │  │  └──PlayView.ets              // 视频滑动播放组件                         
│  │  └──tabcontent                   // tab内容组件 
│  │     ├──PageAll.ets               // 全部tab页
│  │     ├──PageEntertainment.ets     // 娱乐tab页
│  │     ├──PageGame.ets              // 游戏tab页
│  │     ├──PageLive.ets              // 直播tab页
│  │     ├──PageMovie.ets             // 电影tab页
│  │     └──PageTV.ets                // 电视tab页                        
│  └──viewmodel                        
│     ├──PictureItem.ets              // 图片对象 
│     ├──PictureViewModel.ets         // 图片模型
│     ├──TopBarItem.ets               // 顶部导航对象  
│     ├──TopBarViewModel.ets          // 顶部导航模型  
│     ├──VideoItem.ets                // 视频对象     
│     └──VideoViewModel.ets           // 视频模型
└──entry/src/main/resources           // 应用资源目录

顶部导航场景

应用首页首页使用Swiper组件实现了顶部导航的应用场景。用户点击不同的分类标题,会切换展示不同的界面内容。同时也支持用户左右滑动界面,对应导航标题联动变化的效果。

实现这种效果,我们只需将界面划分为两部分:导航栏与内容区。导航栏使用自定义组件TopBar实现,内容区使用Swiper组件实现。

@State和@Link装饰符配合使用,实现TopBar组件标题与Swiper组件索引的双向绑定。内容区内容滑动时,会触发Swiper的onChange事件,并改变索引index的值。前面已经通过特定修饰符实现了索引的双向绑定。因此该索引值的变化会使TopBar的索引值同步变化,实现TopBar和Swiper的联动效果。

// SwiperIndex.ets
struct SwiperIndex {
  // 索引值双向绑定 实现联动效果.
  @State index: number = 0;

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
      TopBar({ index: $index })
      Swiper() {
        PageAll()
        PageMovie()
        PageTV()
        PageEntertainment()
        PageLive()
        PageGame()
      }
      .index(this.index)
      .indicator(false)
      .loop(false)
      .onChange((index: number) => {
        this.index = index;
      })
    }
    .backgroundColor($r('app.color.start_window_background'))
  }
}

点击导航栏中的不同标题时,会触发TopBar中的onClick事件,并改变对应的索引值。同理,该索引的变化会使Swiper的索引值同步变化,实现Swiper和TopBar的联动效果。

// TopBar.ets
export struct TopBar {
  // 索引值双向绑定 实现联动效果
  @Link index: number;
  private tabArray: Array<TopBarItem> = initializeOnStartup();

  build() {
    Row({ space: CommonConstants.SPACE_TOP_BAR }) {
      ForEach(this.tabArray,
        (item: TopBarItem) => {
          Text(item.name)
            .fontSize(this.index === item.id ? $r('app.float.font_size_checked') : $r('app.float.font_size_unchecked'))
            .fontColor(Color.Black)
            .textAlign(TextAlign.Center)
            .fontWeight(this.index === item.id ? FontWeight.Bold : FontWeight.Regular)
            .onClick(() => {
              this.index = item.id;
            })
        }, (item: TopBarItem) => JSON.stringify(item))
    }
    .margin({ left: CommonConstants.ADS_LEFT })
    .width(CommonConstants.FULL_WIDTH)
    .height(CommonConstants.TOP_BAR_HEIGHT)
  }
}

最终实现导航栏与内容区的双向联动效果。

轮播图场景

轮播图常见于各种应用首页,用于各类信息、资讯的轮番展示。本应用使用Swiper组件,同样实现了这一能力。“全部”页签的“电影精选”部分,即为一个电影内容的轮播模块。它可以切换展示不同电影内容。

我们将轮播图模块定义为一个自定义组件Banner。在Banner组件创建新实例时,会初始化轮播内容并开启定时任务。定时任务通过调用swiperController.showNext()方法,控制Swiper组件切换内容展示。

// Banner.ets
aboutToAppear() {
  // 内容数据初始化
  this.imageArray = initializePictures(PictureType.BANNER);
  // 开启定时轮播
  startPlay(this.swiperController);
}

// PictureViewModel.ets
export function startPlay(swiperController: SwiperController) {
  let timerId = setInterval(() => {
    swiperController.showNext();
  }, CommonConstants.SWIPER_TIME);
  timerIds.push(timerId);
}

在Swiper组件内,将初始化数据进行循环渲染。配合开启的定时任务,循环播放。

// Banner.ets
build() {
  Swiper(this.swiperController) {
    ForEach(this.imageArray, (item: PictureItem) => {
      Stack({ alignContent: Alignment.TopStart }) {
        Image(item.image)
          ...
        Column() {
          Text($r('app.string.movie_classic'))
            .textStyle($r('app.float.font_size_description'), CommonConstants.FONT_WEIGHT_LIGHT)
            ...
          Text(item.name)
            .textStyle($r('app.float.font_size_title'), CommonConstants.FONT_WEIGHT_BOLD)
        }
        ...
      }
      .height(CommonConstants.FULL_HEIGHT)
      .width(CommonConstants.FULL_WIDTH)
    }, (item: PictureItem) => JSON.stringify(item))
  }
  ...
}

视频滑动播放场景

视频滑动播放是Swiper组件的另一个常见应用场景。点击应用首页中的视频图片,会跳转至视频播放界面。我们可以通过上下滑动,切换播放的视频内容。

视频播放界面通过函数initializeOnStartup初始化视频内容。在Swiper组件内通过循环渲染的方式,将各个视频内容渲染成自定义组件PlayView。这样每一个视频内容就是一个Swiper的子组件,就可以通过滑动的方式切换播放内容。

// PageVideo.ets
build() {
  Column() {
    Swiper() {
      ForEach(this.videoArray, (item: VideoItem, index: number) => {
        PlayView({
          index: $index,
          pageShow: $pageShow,
          item: item,
          barPosition: index
        });
      }, (item: VideoItem) => JSON.stringify(item))
    }
    .width(CommonConstants.FULL_WIDTH)
    .height(CommonConstants.FULL_HEIGHT)
    .indicator(false)
    .loop(false)
    .vertical(true)
    .onChange((index: number) => {
      this.index = index;
    })
  }
}

在自定义组件PlayView中,通过Video来控制视频播放。另外,结合Stack容器组件,在视频内容上叠加点赞、评论、转发等内容。

// PlayView.ets
build() {
  Stack({ alignContent: Alignment.End }) {
    Video({
      src: this.item.src,
      controller: this.videoController
    })
      .controls(false)
      .autoPlay(this.playState === PlayState.START ? true : false)
      .objectFit(ImageFit.Fill)
      .loop(true)
      .height(CommonConstants.WIDTH_VIDEO)
      .width(CommonConstants.FULL_WIDTH)
      .onClick(() => {
        if (this.playState === PlayState.START) {
          this.playState = PlayState.PAUSE;
          this.videoController.pause();
        } else if (this.playState === PlayState.PAUSE) {
          this.playState = PlayState.START;
          this.videoController.start();
        }
      })

    NavigationView()
    CommentView({ item: this.item })
    DescriptionView()
  }
  .backgroundColor(Color.Black)
  .width(CommonConstants.FULL_WIDTH)
  .height(CommonConstants.FULL_HEIGHT)
}

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 使用Swiper组件实现顶部导航、轮播图、视频滑动播放等场景。
  2. 使用Stack组件实现堆叠布局。
  3. 使用@Extend快速定义并复用组件的自定义样式。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→HarmonyOS教学视频

HarmonyOS教学视频:语法ArkTS、TypeScript、ArkUI等…视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取完整版白皮书方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF

在这里插入图片描述

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. .……

在这里插入图片描述


二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

在这里插入图片描述

三、如何快速入门?《鸿蒙基础入门学习指南》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. .……

在这里插入图片描述


四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. .……

在这里插入图片描述


五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 7.网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. .……

在这里插入图片描述


更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

康耐视visionpro-CogFindLineTool工具详细说明

CogFindeLineTool功能说明: 检测图像的直线边缘,实现边缘的定位、测量。 CogFindeLineTool操作说明: ①.打开工具栏,双击或点击鼠标拖拽添加CogFindLineTool工具 ②.添加输入图像,点击鼠标右键“链接到”选择输入图像或以连线拖拽的方式选择相应输入图像 ③. 所选空间名…

振弦采集仪在预防地质灾害监测中的作用与应用前景

振弦采集仪在预防地质灾害监测中的作用与应用前景 振弦采集仪&#xff08;String Vibrating Sensor&#xff0c;简称SVM&#xff09;是一种用于地质灾害监测的重要仪器&#xff0c;它通过测量地面振动信号来预测和预警地质灾害的发生。SVM的作用在于提供实时、准确的地质灾害监…

威联通安装Kafka

最近在学习 Kafka 的知识&#xff0c;遇到一些问题网上搜到的信息不全。想要在本地安装一个 Kafka 进行验证&#xff0c;想到了之前买的 Nas 就开始折腾。 用 Docker 的方式安装 Kafka 现在的 Nas 很多都支持 Docker&#xff0c;我买的也支持。威联通的 Docker 叫 Container S…

AugmentedReality之路-通过蓝图启动AR相机(2)

本文实现打开AR相机和关闭AR相机功能&#xff0c;在主界面点击Start AR按钮后打开AR相机&#xff0c;在主界面点击Stop AR按钮后关闭AR相机 1、启动AR相关插件 通过Edit->Plugins启用AugmentedReality下面的所有插件 2、自定义Pawn 在Content->ARBase目录右键&…

如何降低 BlueNRG-LPS 的开机峰值电流

1. 前言 BlueNRG 系列存在开机瞬间会出现很大的峰值电流的现象&#xff0c;预计有 20ma 左右。针对此现象&#xff0c;经常有客户询问该峰值电流会不会导致设备工作异常&#xff1f;会不会导致电池使用寿命缩短&#xff08;考虑到一般纽扣电池能承受的峰值电流大概在 15ma 左右…

B64843-4M 1553B总线 控制时序、寄存器介绍。

B64843-4M系统架构 注: 1 、 CPU ADDRESS LATCH 信号由带地址 / 数据复用总线的处理器提供,对不带地址 / 数据复用总线的处理器,CPU ADDRESS LATCH 信号与 3.3V 信号连接。 2、如果 POLARITY_SEL="1" , RD/信号为高时读使能,为低时写使POLARITY_S…

Codeforces Round 937 (Div. 4)

Codeforces Round 937 (Div. 4) Codeforces Round 937 (Div. 4) A. Stair, Peak, or Neither? 题意&#xff1a;略 思路&#xff1a;照着题模拟&#xff1b; AC code&#xff1a; void solve() {int a, b, c; cin >> a >> b >> c;if (a < b) {if (…

【一种基于改进A*算法和CSA-APF算法的混合路径规划方法】—— 论文阅读

论文题目&#xff1a;A Hybrid Path Planning Method Based on Improved A∗ and CSA-APF Algorithms 1 摘要 大问题&#xff1a;复杂动态环境下全局路径规划难以避开动态障碍物&#xff0c;且局部路径容易陷入局部最优的问题 问题1&#xff1a;针对A*算法产生冗余路径节点和…

基于Python的电商特产数据可视化分析与推荐系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 利用网络爬虫技术从某东采集某城市的特产价格、销量、评论等数据&#xff0c;经过数据清洗后存入数据库&#xff0c;并实现特产销售、市场占有率、价格区间等多维度的可视化统计分析&#xff0c;并…

2024蓝桥杯每日一题(背包2)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一&#xff1a;包子凑数 试题二&#xff1a;砝码称重 试题三&#xff1a;倍数问题 试题一&#xff1a;包子称重 【题目描述】 小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 N 种蒸笼&#xf…

row_number 函数和关联更新

生成测试数据&#xff0c;房间号数据如下&#xff1a; CREATE TABLE hotel (floor_nbr,room_nbr) ASSELECT 1,100 FROM DUAL UNION ALLSELECT 1,100 FROM DUAL UNION ALLSELECT 2,100 FROM DUAL UNION ALLSELECT 2,100 FROM DUAL UNION ALLSELECT 3,100 FROM DUAL; 里面的房间号…

Ubuntu18.04安装wireshark

安装wireshark 环境Ubuntu18.04 1.使用root用户进行安装 2.将 wireshark-dev/stable PPA 添加到系统的软件源列表中。系统就可以从该PPA获取Wireshark软件包及其更新了。 apt-add-repository ppa:wireshark-dev/stable3.确保你系统上的软件包信息是最新的&#xff0c;这样在…

若依 3.8.7版本springboot前后端分离 整合mabatis plus

1.去掉mybatis 这一步我没有操作&#xff0c;看别人的博客有说不去掉可能冲突&#xff0c;也可能不冲突&#xff0c;我试下来就没去掉如需要去除&#xff0c;到总的pom.xml中properties标签下的<mybatis-spring-boot.version>x.x.x</mybatis-spring-boot.version>…

灰色预测模型以及matlab软件使用

1&#xff0c;灰色系统简介 著名学者邓聚龙教授于20世纪70年代末、80年代初提出&#xff1a; “ The诞生标志:邓教授第一篇灰色系统论文Control Problems of Grey Systems”&#xff0c;发表于北荷兰出版公司期刊 System & Control Letter,1982, No.5. 1.1 灰色系统&…

|行业洞察·香氛|《小红书2023香水香氛营销宝典-71页》

报告内容的详细解读&#xff1a; 行业格局 预计到2025年&#xff0c;香水市场规模将超过300亿&#xff0c;小红书成为香水种草的重要平台。从2018年到2025年&#xff0c;市场规模持续增长&#xff0c;年增速保持在20%左右。香水市场的热度在节日节点尤为明显&#xff0c;如情…

Golang-Gorm-快速上手

Gorm文档 GORM文档地址 安装依赖 go get -u "gorm.io/driver/mysql"go get -u "gorm.io/gorm"连接数据库 默认连接方式 func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn : "user:passtcp(127.0.0…

docker:在ubuntu中运行docker容器

前言 1 本笔记本电脑运行的ubuntu20.04系统 2 docker运行在ubuntu20.04系统 3 docker镜像使用的是ubuntu18.04&#xff0c;这样拉的 docker pull ubuntu:18.04 4 docker容器中运行的是ubuntu18.04的系统&#xff0c;嗯就是严谨 5 这纯粹是学习笔记&#xff0c;实际上没啥价值。…

JAVA 源码分析Integer的128陷阱

128陷阱介绍及演示 首先什么是128陷阱&#xff1f; Integer包装类两个值大小在-128到127之间时可以判断两个数相等&#xff0c;因为两个会公用同一个对象&#xff0c;返回true&#xff0c; 但是超过这个范围两个数就会不等&#xff0c;因为会变成两个对象&#xff0c;返回fal…

Linux第85步_EXTI外部中断

1、在stm32mp157d-atk.dts文件中添加“led0”和“key0”节点 打开虚拟机上“VSCode”&#xff0c;点击“文件”&#xff0c;点击“打开文件夹”&#xff0c;点击“zgq”&#xff0c;点击“linux”&#xff0c;点击“atk-mp1”&#xff0c;点击“linux”&#xff0c;点击“my_l…

RecyclerView 调用 notifyItemInserted 自动滚动到底部的问题

项目中发现一个奇怪的现象 RecyclerView 加载完数据以后&#xff0c;调用 notifyItemInserted 方法&#xff0c;RecyclerView 会滑动到底部。 简化后的效果图&#xff1a; 因为这个 RecyclerView 的适配器有一个 FootViewHolder&#xff0c;所以怀疑是 FootViewHolder 的问题…