积分431 / 贡献0

提问31答案被采纳5文章47

[经验分享] OpenHarmony应用开发之轮播图实现教程 原创

润开鸿_坚果 显示全部楼层 发表于 2023-11-27 06:49:26

本帖最后由 yeyao 于 2023-11-27 08:41 编辑

OpenHarmony应用开发之轮播图实现教程

效果图

image-20231126154851803

image-20231126154907218

image-20231126154926113

具体实现

我们在OpenHarmony的ark ui 里面列表使用我们的Swiper组件来实现 我们的轮播图

准备数据源

import { PictureItem } from '../bean/PictureItem';
​
/**
 * Pictures of banner.
 */
export const PICTURE_BANNER: PictureItem[] = [
  { 'id': '1', 'name': '怒海', 'description': '怒海波涛', 'image': $r('app.media.image1') },
  { 'id': '2', 'name': '大山深处', 'description': '大山深处感人的亲情之歌', 'image': $r('app.media.image2') },
  { 'id': '3', 'name': '荒漠', 'description': '荒漠的亲情之歌', 'image': $r('app.media.image3') }
];
​
/**
 * type of pictures.
 */
export enum PictureType {
  BANNER = 'banner',
}

Bean类

​
/**
 * Picture entity class.
 */
export class PictureItem {
  id: string;
  name: string;
  description: string;
  image: Resource;
​
  constructor(id: string, name: string, description: string, image: Resource) {
    this.id = id;
    this.name = name;
    this.description = description;
    this.image = image;
  }
}

宽高常量配置

​
/**
 * Common constants for all features.
 */
export class CommonConstants {
​
  /**
   * animation duration of tab content switching.
   */
  static readonly DURATION_ADS = 200;
​
​
  /**
   * height of carousel title.
   */
  static readonly HEIGHT_CAROUSEL_TITLE = 90;
​
  /**
   * fontSize of description.
   */
  static readonly FONT_SIZE_DESCRIPTION = 12;
  /**
   * font size of title.
   */
  static readonly FONT_SIZE_TITLE = 20;
​
  static readonly FONT_WEIGHT_LIGHT = 400;
  /**
   * bold font.
   */
  static readonly FONT_WEIGHT_BOLD = 700;
​
  /**
   * page layout weight.
   */
  static readonly LAYOUT_WEIGHT = 1;
​
  /**
   * border angle.
   */
  static readonly BORDER_RADIUS = 12;
​
  /**
   * line height for more.
   */
  static readonly LINE_HEIGHT_MORE = 19;
  /**
   * rolling duration.
   */
  static readonly SWIPER_TIME = 1500;
  /**
   * margin of text bottom.
   */
  static readonly BOTTOM_TEXT = 4;
​
  /**
   * margin of banner top.
   */
  static readonly TOP_ADS = 12;
  /**
   * margin of banner left.
   */
  static readonly ADS_LEFT = 12;
​
  /*
   * maximum width.
   */
  static readonly FULL_WIDTH = '100%';
  /**
   * maximum height.
   */
  static readonly FULL_HEIGHT = '100%';
  /**
   * width of tab page.
   */
  static readonly PAGE_WIDTH = '100%';
  /**
   * height of banner.
   */
  static readonly HEIGHT_BANNER = '27%';
​

}

具体布局

​
import router from '@ohos.router';
import { PictureItem } from '../bean/PictureItem';
import { PictureType } from '../constants/PictureConstants';
import { initializePictures, startPlay, stopPlay } from './PictureViewModel';
import { CommonConstants } from '../constants/CommonConstant';
​
​
​
@Extend(Text) function textStyle(fontSize: number, fontWeight: number) {
  .fontSize(fontSize)
  .fontColor($r('app.color.start_window_background'))
  .fontWeight(fontWeight)
}
​
/**
 * Carousel banner.
 */
@Component
export struct Banner {
  @State index: number = 0;
  private imageArray: Array<PictureItem> = [];
  private swiperController: SwiperController = new SwiperController();
​
  aboutToAppear() {
    // Data Initialization.
    this.imageArray = initializePictures(PictureType.BANNER);
    // Turn on scheduled task.
    startPlay(this.swiperController);
  }
​
  aboutToDisappear() {
    stopPlay();
  }
​
  build() {
    Swiper(this.swiperController) {
      ForEach(this.imageArray, item => {
        Stack({ alignContent: Alignment.TopStart }) {
          Image(item.image)
            .objectFit(ImageFit.Fill)
            .height(CommonConstants.FULL_HEIGHT)
            .width(CommonConstants.FULL_WIDTH)
            .borderRadius(CommonConstants.BORDER_RADIUS)
            .align(Alignment.Center)
            .onClick(() => {
             console.log("点击事件 item"+item.id)
            })
​
          Column() {
            Text($r('app.string.movie_classic'))
              .textStyle(CommonConstants.FONT_SIZE_DESCRIPTION, CommonConstants.FONT_WEIGHT_LIGHT)
              .margin({ bottom: CommonConstants.BOTTOM_TEXT })
            Text(item.name)
              .textStyle(CommonConstants.FONT_SIZE_TITLE, CommonConstants.FONT_WEIGHT_BOLD)
          }
          .alignItems(HorizontalAlign.Start)
          .height(CommonConstants.HEIGHT_CAROUSEL_TITLE)
          .margin({ top: CommonConstants.TOP_ADS, left: CommonConstants.ADS_LEFT })
        }
        .height(CommonConstants.FULL_HEIGHT)
        .width(CommonConstants.FULL_WIDTH)
      }, item => JSON.stringify(item))
    }
    .width(CommonConstants.PAGE_WIDTH)
    .height(CommonConstants.HEIGHT_BANNER)
    .index(this.index)
    .indicatorStyle({ selectedColor: $r('app.color.start_window_background') })
    .indicator(true)
    .duration(CommonConstants.DURATION_ADS)
  }
}

使用 indicator 属性设置是否支持自动轮播

.indicator(true)

设置自动轮播间隔时间

.duration(CommonConstants.DURATION_ADS)

viewmodel 实现

import { PictureItem } from '../bean/PictureItem';
import { PICTURE_BANNER} from '../constants/PictureConstants';
import { PictureType } from '../constants/PictureConstants';
import { CommonConstants } from '../constants/CommonConstant';
​
/**
 * Initialize picture data according to type.
 *
 * @param initType Init type.
 */
export function initializePictures(initType: string): Array<PictureItem> {
  let imageDataArray: Array<PictureItem> = [];
  switch (initType) {
    case PictureType.BANNER:
      PICTURE_BANNER.forEach((item) => {
        imageDataArray.push(new PictureItem(item.id, item.name, item.description, item.image));
      })
      break;
    default:
      break;
  }
  return imageDataArray;
}
​
let timerIds: number[] = [];
​
/**
 * start scheduled task.
 *
 * @param swiperController Controller.
 */
export function startPlay(swiperController: SwiperController) {
  let timerId = setInterval(() => {
    swiperController.showNext();
  }, CommonConstants.SWIPER_TIME);
  timerIds.push(timerId);
}
​
/**
 * stop scheduled task.
 */
export function stopPlay() {
  timerIds.forEach((item) => {
    clearTimeout(item);
  })
}
​

最后总结:

ArkUI写法和Flutter非常的像 有兴趣的同学可以多尝试哈 今天的文章就讲到这里 。最后呢 希望我都文章能帮助到各位同学工作和学习 如果你觉得文章还不错麻烦给我三连 关注点赞和转发 谢谢

项目地址 :

码云:https://gitee.com/qiuyu123/hmsbanner

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部