这学期我学习了鸿蒙,想用鸿蒙做一个鸿蒙商城app,来展示一下。
项目环境搭建:
1.开发环境:DevEco Studio
2.开发语言:ArkTS
3.运行环境:Harmony NEXT base1
软件要求:
DevEco Studio 5.0.0 Release
HarmonyOS SDK版本:API version 10
硬件要求:
华为手机或能够顺利运行DevEco Studio上的华为手机模拟器的电脑
1.欢迎界面实现
欢迎界面的实现过程如下:首先,我们创建了一个名为Index的组件,使用Column容器组件构建布局,并在其中添加了空白空间、文本和另一个Column容器。文本内容为“探索”和“购物乐趣”,字体大小为50,颜色为白色,并且加粗。接着,在Column容器中添加了一张图片,图片资源位于resource文件夹下的logo图片素材中。整个欢迎界面的背景采用了渐变色,颜色从#FF8469渐变到#FC4355。为了实现欢迎界面的闪屏变化效果,我们添加了一个透明度变化的动画,使用属性动画实现渐变过渡。在Column组件上添加了opacity属性,并使用state修饰器声明了一个状态变量opacityValue,初始值为0.3。在生命周期函数onPageShow中,我们将opacityValue设置为1,使组件完全显示。动画的duration参数设置为1500ms,iterations参数设置为3次播放。动画完成后,会触发onFinish方法。
- @Entry
- @Component
- struct Index {
- build() {
- Column(){
- Blank()
- Column(){
-
- }
- .height('100%')
- .width('100%').linearGradient({
- colors: [
- ["#B3CDE3", 0], // 浅蓝色
- ["#7F8FA6", 0.5], // 中等蓝色
- ["#2C3E50", 1] // 深蓝色
- ]})
- }
- }
- }
-
- @Entry
- @Component
- struct LaunchPage {
-
- build() {
- Column() {
- Blank()
- Column(){
- Text('探索')
- .fontSize(50)
- .fontColor(Color.White)
- Text('购物乐趣')
- .fontSize(50)
- .fontColor(Color.White)
- }
- }
- .height('100%')
- .width('100%').linearGradient({
- colors: [
- ["#B3CDE3", 0], // 浅蓝色
- ["#7F8FA6", 0.5], // 中等蓝色
- ["#2C3E50", 1] // 深蓝色
- ]})
- }
- }
-
记得把logo图片放在如下目录里面resource文件夹下面
logo图片素材
- import router from '@ohos.router';
- @Entry
- @Component
- struct Index {
- @State opacityValue: number = 0.3;
- onPageShow(){
- this.opacityValue = 1;
- }
- build() {
- Column(){
- Blank()
- Column(){
- Text('探索')
- .fontSize(50)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bold)
- Text('购物乐趣')
- .fontSize(50)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bold)
- }.alignItems(HorizontalAlign.Start).opacity(this.opacityValue)
- .animation({
- duration: 1500,
- iterations:3,
- onFinish: () => {
- router.pushUrl({
- url: '/pages/LaunchPage'
- });
- }
- })
- Blank()
- Blank()
- Image($r('app.media.logo')).width(200)
- }.margin({top:30})
- .height('100%')
- .width('100%').linearGradient({
- colors: [
- ["#B3CDE3", 0], // 浅蓝色
- ["#7F8FA6", 0.5], // 中等蓝色
- ["#2C3E50", 1] // 深蓝色
- ]})
- }
- }
效果图如下
到此我们完成了欢迎界面的布局
接下来我们将实现欢迎界面的闪屏变化效果,可以使用属性动画来实现渐变过渡的效果
我们添加一个组件,透明度变化的动画可以使用属性动画来实现渐变过渡的效果,在column组件上添加opacity属性,透明度的变化是一个动态的值,这里我们使用state修饰器声明一个状态变量,状态变量变化会触发UI刷新,默认的透明度设置为0.3,然后在生命周期函数,on page show中设置透明度的值为一让组件完全显示,然后设置animation属性动画的参数duration参数设置动画时长默认值为1000ms,这里我们设置为1500ms,iterations参数设置播放次数默认值播放一次,这里我们设置播放三次,最后添加UNFINISH方法,该方法在动画播放完成时触发
- @Entry
- @Component
- struct Index {
- @State opacityValue: number = 0.3;
- onPageShow(){
- this.opacityValue = 1;
- }
- build() {
- Column(){
- Blank()
- Column(){
- Text('探索')
- .fontSize(50)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bold)
- Text('购物乐趣')
- .fontSize(50)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bold)
- }.alignItems(HorizontalAlign.Start).opacity(this.opacityValue)
- .animation({
- duration: 1500,
- iterations:3,
- onFinish: () => {
- }
- })
- Blank()
- Blank()
- Image($r('app.media.logo')).width(200)
- }
-
- .height('100%')
- .width('100%').linearGradient({
- colors: [['#FF8469',0],[ '#FC4355',1] ]})
- }
- }
现在我们在预览界面查看欢迎界面的最终效果
2.引导页实现
接下来,我们实现引导页。创建launchPage页面
在index页面导入import router from '@ohos.router';
引导页的布局采用垂直方向,使用Column容器组件,并设置宽度和高度。背景同样使用渐变色。
LaunchPage页面
-
- @Entry
- @Component
- struct LaunchPage {
-
- build() {
- Column() {
-
- }
- .height('100%')
- .width('100%').linearGradient({
- colors: [
- ["#B3CDE3", 0], // 浅蓝色
- ["#7F8FA6", 0.5], // 中等蓝色
- ["#2C3E50", 1] // 深蓝色
- ]})
- }
- }
-
引导页创建好后,我们使用页面路由跳转到应用内的指定页面。在欢迎界面中导入路由模块,
import router from '@ohos.router';
并在动画效果结束后调用路由的push url方法,配置跳转选项,并传入引导页的URL。
引导页的功能包括通过左右滑动切换页面,使用Tabs组件实现内容视图的切换。每个页签对应一个TabContent组件。
我们创建了一个banner model对象,包含id、title、subtitle和image属性,并指定了引导页的数据源。在Tabs组件中,我们添加了三个TabContent组件,并通过forEach接口基于数组类型数据进行循环渲染。每个TabContent组件中,我们创建了一个Column组件,设置宽度、高度和内边距,并在其中添加了Text和Image组件,显示标题、内容和图片。我们还创建了一个页码指示器,使用Roll组件渲染页码指示器,同样使用forEach执行循环渲染。最后,当切换到最后一个页签时,显示一个“立即体验”的按钮,点击后跳转到商城首页。在Button组件的点击事件中,我们调用路由的push url方法,传入首页的URL,实现跳转。
LaunchPage页面代码如下
- import BannerModel from '../models/BannerModel'
- import { router } from '@kit.ArkUI'
-
- @Entry
- @Component
- struct LaunchPage {
- currentIndex: number = 0
- @State index: number = 0
- @State items: BannerModel[] =[
- { id:0,
- title: '甄选推荐',
- subtitle: '精心挑选,为您呈现',
- image:'https://img1.wushang.com/pn/wsec-img1/2021/6/9/d8328eef-8552-4d4e-968c-7030836e46f1.jpg?x-oss-process=image/resize,w_800,h_800',
-
- },
- { id:1,
- title: '手机专区',
- subtitle: '手机特惠区,尽享购物惊喜',
- image: 'https://img.alicdn.com/i2/1114511827/O1CN018TdXCN1PMoOG25L5Q_!!1114511827.jpg',
-
- },
- { id:2,
- title: '电脑专区',
- subtitle: '电脑特区,装备你的数位生活',
- image: 'https://tse3-mm.cn.bing.net/th/id/OIP-C.nDvymf_rVmMgx0RnuRbwOQHaGM?rs=1&pid=ImgDetMain',
-
- }
-
- ]
- build() {
- Column() {
- Tabs(){
- ForEach(this.items, (item: BannerModel) => {
- TabContent(){
- Column() {
- Text(item.title)
- .fontSize(50)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bold)
- Text(item.subtitle)
- .fontSize(30)
- .fontColor(Color.White)
- .fontWeight(FontWeight.Bold)
- Blank()
- Image(item.image)
- .width(300)
- .height(300)
- .objectFit(ImageFit.Contain)
- .interpolation(ImageInterpolation.High)
- Row({ space: 10}){
- ForEach(this.items,(item:BannerModel) => {
- Rect({
- width: 10,height: 10
- }).fill(this.currentIndex === item.id ? Color.White : Color.Gray)
-
- })
- }.margin({ top: 30})
-
- if (this.currentIndex == this.items.length-1) {
- Button({ type: ButtonType.Capsule }){
- Text('立即体验').fontColor(Color.White).fontSize(18)
- }
- .width(200)
- .height(50)
- .backgroundColor(Color.Transparent)
- .borderWidth(2)
- .borderColor(Color.Black)
- .borderRadius(6)
- .onClick(() => {
- router.pushUrl({
- url: 'pages/HomePage'
- })
- })
- .margin({ top: 50})
- }
- }.width('100%').height('100%').padding({ top: 50,left: 50,right: 50})
- }
- })
-
- }.width('100%').height('100%').onChange((value: number)=>{
- this.currentIndex = value
- })
-
- }.height('100%')
- .width('100%').linearGradient({
- colors: [
- ["#B3CDE3", 0], // 浅蓝色
- ["#7F8FA6", 0.5], // 中等蓝色
- ["#2C3E50", 1] // 深蓝色
- ]})
- }
- }
LaunchPage页面预览效果图如下所示
3.首页自定义导航栏选项卡
-
-
- @Entry
- @Component
- struct HomePage {
- @State currentIndex:number = 0
- private tabsController: TabsController = new TabsController()
- @Builder
- TabBuilder(title:string,image:Resource,selectedImage:Resource,tag:number){
- Column(){
- Image(this.currentIndex === tag?selectedImage:image)
- .size({width: 40, height: 40})
- .objectFit(ImageFit.Contain).interpolation(ImageInterpolation.High)
- Text(title).fontSize(14)
- .fontColor(this.currentIndex === tag?Color.Blue:Color.Black)
- }.width('100%').height(50).justifyContent(FlexAlign.Center)
- .border({
- width: {top: 1},
- color: Color.White
- })
- .onClick(()=>{
- this.currentIndex = tag
- this.tabsController.changeIndex(this.currentIndex)
- })
- }
- build() {
- Column(){
- Tabs({barPosition:BarPosition.End,controller:this.tabsController}){
- TabContent(){
- Text('首页')
- }.tabBar(this.TabBuilder('首页',$r('app.media.home'),$r('app.media.home_selected'),0))
- TabContent(){
- Text('分类')
- }.tabBar(this.TabBuilder('分类',$r('app.media.sort'),$r('app.media.sort_selected'),0))
- TabContent(){
- Text('购物车')
- }.tabBar(this.TabBuilder('购物车',$r('app.media.cart'),$r('app.media.cart_selected'),0))
- TabContent(){
- Text('我的')
- }.tabBar(this.TabBuilder('我的',$r('app.media.my'),$r('app.media.my_selected'),0))
- }.width('100%').height('100%').barHeight(80).backgroundColor(Color.White)
- .onChange((index:number)=>{
- this.currentIndex = index
- })
- }.width('100%').height('100%')
- }
- }
-
-
-
效果如下图所示
评论记录:
回复评论: