鸿蒙 ark ui 轮播图实现教程

1,398 阅读1分钟

前言:

各位同学有段时间没有见面 因为一直很忙所以就没有去更新博客。最近有在学习这个鸿蒙的ark ui开发 因为鸿蒙不是发布了一个鸿蒙next的测试版本 明年会启动纯血鸿蒙应用 所以我就想提前给大家写一些博客文章

效果图

image.png

image.png

image.png

具体实现

我们在鸿蒙的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',
}

image.png

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

项目地址 :

码云:gitee.com/qiuyu123/hm…