HarmonyOS第一课 05 从简单的页面开始-开发代码2



本文的内容是使用ArkUI继续完成一个简单的页面。上节内容已经完成了上半部分,接下来继续完成下半部分。

页面具体实现如图:


下载本节内容的素材。「链接」


创建赋能套件

在Index.ets文件中新建控件EnablementItem

需要完成的案例:


EnablementItem布局:


EnablementItem布局代码:

@Preview
@Component
struct EnablementItem{
  private title: string = 'HarmonyOS第一课';
  private brief: string = '基于真实的开发场景,提供向导式学习,多维度融合课程等内容,给开发者提供全新的学习体验。';

  build() {
    Column(){
      /**
       * 使用$r的方式给Image组件设置图片资源,设置图片宽度为100%,即宽度与根容器Column保持一致。

       设置填充效果为cover模式,即保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。
       */
      Image($r('app.media.enablement_pic1')).width('100%').objectFit(ImageFit.Cover)
        .height(96)
        // 图片圆角边框
        .borderRadius({
          topLeft:16,
          topRight:16
        })

      /*
      接下来给Text组件添加属性,textOverFlow属性设置文本超长时的显示方式,在这里我们设置它的值为Ellipsis,表示超长时使用省略号替代。

maxLines属性设置文本的最大行数,我们设置title最多显示一行,brief最多显示两行。

到这里我们完成了“赋能套件介绍”网格布局Item的创建。
       */
      Text(this.title)
        .height(19)
        .width('100%')
        .fontSize(14)
        .textAlign(TextAlign.Start)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(1)
        .fontWeight(400)
        .padding({ left: 12, right: 12 })
        .margin({ top: 8 })
      // 第二行文字
      Text(this.brief)
        .height(32)
        .width('100%')
        .fontSize(12)
        .textAlign(TextAlign.Start)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(2)
        .fontWeight(400)
        .fontColor('rgba(0, 0, 0, 0.6)')
        .padding({ left: 12, right: 12 })
        .margin({ top: 2 })

    }.width(160)
    .height(169)
    .borderRadius(16)
    .backgroundColor(Color.White)
    
  }
}

整个index.ets的代码:

import image from '@ohos.multimedia.image';

// 新建一个Banner类,便于滑动
class BannerClass{
  id:string="";//用于唯一标识每一张图片资源,在之后的ForEach内容中我们会看到其作用
  imgSrc:ResourceStr = ""; //imageSrc属性,用于存储图片地址
  url:string =""; //用于存储Banner图片点击后跳转到的在线网页地址,在之后的跳转功能中会用到。

  // 按住alt+insert键,可以自动生成构造方法
  constructor(id: string, imgSrc: ResourceStr, url: string) {
    this.id = id;
    this.imgSrc = imgSrc;
    this.url = url;
  }
}


@Entry
@Component
struct Index {
  @State message: string = '快速入门';

  build() {
    Column() {
      Text(this.message)
        //.id('HelloWorld') // 这个不需要
        .fontSize(24)
        .fontWeight('700')
        .width("100%")
        .textAlign(TextAlign.Start)
        .padding({"left":16})
        .fontFamily("HarmonyHeiTi-Bold")
        .lineHeight(33)
      // 把Banner放在文字的下面
      Banner()
    }
    .height('100%')
    .width('100%')
    .backgroundColor("#F1F3F5")
  }
}

// 新建一个Banner
@Component
@Preview
struct Banner{

  @State bannerList: Array<BannerClass>=[
    new BannerClass('pic0',$r('app.media.banner_pic0'),'https://developer.huawei.com'),
    new BannerClass('pic1',$r('app.media.banner_pic1'),'https://developer.huawei.com'),
    new BannerClass('pic2',$r('app.media.banner_pic2'),'https://developer.huawei.com'),
    new BannerClass('pic3',$r('app.media.banner_pic3'),'https://developer.huawei.com'),
    new BannerClass('pic4',$r('app.media.banner_pic4'),'https://developer.huawei.com'),
    new BannerClass('pic5',$r('app.media.banner_pic5'),'https://developer.huawei.com')

  ]

  build() {
    // 滑动块,将image包裹起来
    Swiper(){
      
      ForEach(this.bannerList,(item:BannerClass,index:number)=>{
        Image(item.imgSrc).objectFit(ImageFit.Contain)
          .width("100%")
            // 这里能否合并left和right?
          .padding({"left":16,"right":16,"top":11})
            // 圆角边框
          .borderRadius(16)
      },(item:BannerClass,index:number)=>item.id)

    }
    //设置一下Swiper的属性。其中,autoPlay控制是否自动轮播子组件,loop属性控制是否循环播放,
    // indicator属性自定义导航点的位置和样式。
    .autoPlay(true)
    .loop(true)
    .indicator(new DotIndicator().color('#1a000000').selectedColor("#0a59f7"))


  }
}

@Preview
@Component
struct EnablementItem{
  private title: string = 'HarmonyOS第一课';
  private brief: string = '基于真实的开发场景,提供向导式学习,多维度融合课程等内容,给开发者提供全新的学习体验。';

  build() {
    Column(){
      /**
       * 使用$r的方式给Image组件设置图片资源,设置图片宽度为100%,即宽度与根容器Column保持一致。

       设置填充效果为cover模式,即保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。
       */
      Image($r('app.media.enablement_pic1')).width('100%').objectFit(ImageFit.Cover)
        .height(96)
        // 图片圆角边框
        .borderRadius({
          topLeft:16,
          topRight:16
        })

      /*
      接下来给Text组件添加属性,textOverFlow属性设置文本超长时的显示方式,在这里我们设置它的值为Ellipsis,表示超长时使用省略号替代。

maxLines属性设置文本的最大行数,我们设置title最多显示一行,brief最多显示两行。

到这里我们完成了“赋能套件介绍”网格布局Item的创建。
       */
      Text(this.title)
        .height(19)
        .width('100%')
        .fontSize(14)
        .textAlign(TextAlign.Start)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(1)
        .fontWeight(400)
        .padding({ left: 12, right: 12 })
        .margin({ top: 8 })
      // 第二行文字
      Text(this.brief)
        .height(32)
        .width('100%')
        .fontSize(12)
        .textAlign(TextAlign.Start)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(2)
        .fontWeight(400)
        .fontColor('rgba(0, 0, 0, 0.6)')
        .padding({ left: 12, right: 12 })
        .margin({ top: 2 })

    }.width(160)
    .height(169)
    .borderRadius(16)
    .backgroundColor(Color.White)
    
  }
}

创建“入门教程”列表视图Item

需要完成的示例


TutorialItem布局代码




@Preview
@Component
struct TutorialItem {
  private title: string = 'Step1 快速入门介绍';
  private brief: string = '本篇教程实现了快速入门——一个用于了解和学习HarmonyOS的应用程序 。';

  build() {
    // TutorialItem 布局代码
    Row() {
      Column() {
        // 这里的两个文本样式有些多余了,不知有没有办法写一个样式,然后套用
        Text(this.title)
          .height(19)
          .width('100%')
          .fontSize(14)
          .textAlign(TextAlign.Start)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .maxLines(1)
          .fontWeight(400)
          .margin({ top: 4 })

        Text(this.brief)
          .height(32)
          .width('100%')
          .fontSize(12)
          .textAlign(TextAlign.Start)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .maxLines(2)
          .fontWeight(400)
          .fontColor('rgba(0, 0, 0, 0.6)')
          .margin({ top: 5 })
      }
      .height('100%')
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
      .margin({ right: 12 })

      Image($r('app.media.enablement_pic1'))
        .height(64)
        .width(108)
        .objectFit(ImageFit.Cover)
        .borderRadius(16)
    }.width('100%')
    .height(88)
    .borderRadius(16)
    .backgroundColor(Color.White)
    .padding(12)
    .alignItems(VerticalAlign.Top)
  }
}

已经完成了两个单独的组件,接下来需要循环将这些组件显示.


下载多个文件素材「链接」

形成网格和列表

观察单个item视图,可以发现,每一个item是由其文章的对应标题(title)、简介(brief)、文章配图(imageSrc)和点击后即将跳转的网页地址(webUrl)组成的。


建立命名为EnablementView的空组件和TutorialView的空组件,并用@Preview装饰器装饰,以便单独预览组件。


这里两个控件设计有点复杂,接下来看重点

1,Grid循环,

2,List循环,

在这两个循环中,主要使用了@Prop这个装饰器,将变量传入到对应的组件中,看示例代码



然后另外一个也是一样



主要就是这两处代码.其余完整的index.ets代码如下:

import image from '@ohos.multimedia.image';

// 新建一个Banner类,便于滑动
class BannerClass{
  id:string="";//用于唯一标识每一张图片资源,在之后的ForEach内容中我们会看到其作用
  imgSrc:ResourceStr = ""; //imageSrc属性,用于存储图片地址
  url:string =""; //用于存储Banner图片点击后跳转到的在线网页地址,在之后的跳转功能中会用到。

  // 按住alt+insert键,可以自动生成构造方法
  constructor(id: string, imgSrc: ResourceStr, url: string) {
    this.id = id;
    this.imgSrc = imgSrc;
    this.url = url;
  }
}

/*
文章的数据结构。在数据结构内为每个文章定义唯一id,并添加其标题(title)、简介(brief)、文章配图(imageSrc)和点击后即将跳转的网页地址(webUrl)属性。
 */
class ArticleClass {
  id: string = '';
  imageSrc: ResourceStr = '';
  title: string = '';
  brief: string = '';
  webUrl: string = '';

  constructor(id: string, imageSrc: ResourceStr, title: string, brief: string, webUrl: string) {
    this.id = id;
    this.imageSrc = imageSrc;
    this.title = title;
    this.brief = brief;
    this.webUrl = webUrl;
  }
}


@Entry
@Component
struct Index {
  @State message: string = '快速入门';

  build() {
    Column() {
      Text(this.message)
        //.id('HelloWorld') // 这个不需要
        .fontSize(24)
        .fontWeight('700')
        .width("100%")
        .textAlign(TextAlign.Start)
        .padding({"left":16})
        .fontFamily("HarmonyHeiTi-Bold")
        .lineHeight(33)
      // 把Banner放在文字的下面,这里需要滚动了
      Scroll() {
        Column() {
          Banner()
          EnablementView()
          TutorialView()
        }
      }
      .layoutWeight(1)
      .scrollBar(BarState.Off)
      .align(Alignment.TopStart)

    }
    .height('100%')
    .width('100%')
    .backgroundColor("#F1F3F5")
  }
}

// 新建一个Banner
@Component
@Preview
struct Banner{

  @State bannerList: Array<BannerClass>=[
    new BannerClass('pic0',$r('app.media.banner_pic0'),'https://developer.huawei.com'),
    new BannerClass('pic1',$r('app.media.banner_pic1'),'https://developer.huawei.com'),
    new BannerClass('pic2',$r('app.media.banner_pic2'),'https://developer.huawei.com'),
    new BannerClass('pic3',$r('app.media.banner_pic3'),'https://developer.huawei.com'),
    new BannerClass('pic4',$r('app.media.banner_pic4'),'https://developer.huawei.com'),
    new BannerClass('pic5',$r('app.media.banner_pic5'),'https://developer.huawei.com')

  ]

  build() {
    // 滑动块,将image包裹起来
    Swiper(){
      
      ForEach(this.bannerList,(item:BannerClass,index:number)=>{
        Image(item.imgSrc).objectFit(ImageFit.Contain)
          .width("100%")
            // 这里能否合并left和right?
          .padding({"left":16,"right":16,"top":11})
            // 圆角边框
          .borderRadius(16)
      },(item:BannerClass,index:number)=>item.id)

    }
    //设置一下Swiper的属性。其中,autoPlay控制是否自动轮播子组件,loop属性控制是否循环播放,
    // indicator属性自定义导航点的位置和样式。
    .autoPlay(true)
    .loop(true)
    .indicator(new DotIndicator().color('#1a000000').selectedColor("#0a59f7"))


  }
}
//同时注释掉前面创建的EnablementItem组件的@Preview注解,方便单独预览TutorialItem组件。
//@Preview
@Component
struct EnablementItem{

  // 等下循环传入进来的item,被该变量接收,使用@Prop 修饰
  @Prop enablementItem: ArticleClass;

  private title: string = 'HarmonyOS第一课';
  private brief: string = '基于真实的开发场景,提供向导式学习,多维度融合课程等内容,给开发者提供全新的学习体验。';

  build() {
    Column(){
      /**
       * 使用$r的方式给Image组件设置图片资源,设置图片宽度为100%,即宽度与根容器Column保持一致。

       设置填充效果为cover模式,即保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。
       */
      Image($r('app.media.enablement_pic1')).width('100%').objectFit(ImageFit.Cover)
        .height(96)
        // 图片圆角边框
        .borderRadius({
          topLeft:16,
          topRight:16
        })

      /*
      接下来给Text组件添加属性,textOverFlow属性设置文本超长时的显示方式,在这里我们设置它的值为Ellipsis,表示超长时使用省略号替代。

maxLines属性设置文本的最大行数,我们设置title最多显示一行,brief最多显示两行。

到这里我们完成了“赋能套件介绍”网格布局Item的创建。
       */
      Text(this.title)
        .height(19)
        .width('100%')
        .fontSize(14)
        .textAlign(TextAlign.Start)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(1)
        .fontWeight(400)
        .padding({ left: 12, right: 12 })
        .margin({ top: 8 })
      // 第二行文字
      Text(this.brief)
        .height(32)
        .width('100%')
        .fontSize(12)
        .textAlign(TextAlign.Start)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(2)
        .fontWeight(400)
        .fontColor('rgba(0, 0, 0, 0.6)')
        .padding({ left: 12, right: 12 })
        .margin({ top: 2 })

    }.width(160)
    .height(169)
    .borderRadius(16)
    .backgroundColor(Color.White)
    
  }
}


@Preview
@Component
struct TutorialItem {

  @Prop tutorialItem: ArticleClass;

  private title: string = 'Step1 快速入门介绍';
  private brief: string = '本篇教程实现了快速入门——一个用于了解和学习HarmonyOS的应用程序 。';

  build() {
    // TutorialItem 布局代码
    Row() {
      Column() {
        // 这里的两个文本样式有些多余了,不知有没有办法写一个样式,然后套用
        Text(this.title)
          .height(19)
          .width('100%')
          .fontSize(14)
          .textAlign(TextAlign.Start)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .maxLines(1)
          .fontWeight(400)
          .margin({ top: 4 })

        Text(this.brief)
          .height(32)
          .width('100%')
          .fontSize(12)
          .textAlign(TextAlign.Start)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .maxLines(2)
          .fontWeight(400)
          .fontColor('rgba(0, 0, 0, 0.6)')
          .margin({ top: 5 })
      }
      .height('100%')
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
      .margin({ right: 12 })

      Image($r('app.media.enablement_pic1'))
        .height(64)
        .width(108)
        .objectFit(ImageFit.Cover)
        .borderRadius(16)
    }.width('100%')
    .height(88)
    .borderRadius(16)
    .backgroundColor(Color.White)
    .padding(12)
    .alignItems(VerticalAlign.Top)
  }
}


@Preview
@Component
struct EnablementView{
  // 需要解析的数据,放在build上面
  @State enablementList: Array<ArticleClass> = [
    new ArticleClass('1', $r('app.media.enablement_pic1'), 'HarmonyOS第一课',
      '基于真实的开发场景,提供向导式学习,多维度融合课程等内容,给开发者提供全新的学习体验。',
      'https://developer.huawei.com/consumer/cn/doc/harmonyos-video-courses/video-tutorials-0000001443535745'),
    new ArticleClass('2', $r('app.media.enablement_pic2'), '开发指南',
      '提供系统能力概述、快速入门,用于指导开发者进行场景化的开发。指南涉及到的知识点包括必要的背景知识、符合开发者实际开发场景的操作任务流(开发流程、开发步骤、调测验证)以及常见问题等。',
      'https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/application-dev-guide-0000001630265101'),
    new ArticleClass('3', $r('app.media.enablement_pic3'), '最佳实践',
      '针对新发布特性及热点特性提供详细的技术解析和开发最佳实践。',
      'https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/topic-architecture-0000001678045510'),
    new ArticleClass('4', $r('app.media.enablement_pic4'), 'Codelabs',
      '以教学为目的的代码样例及详细的开发指导,帮助开发者一步步地完成指定场景的应用开发并掌握相关知识。Codelabs将最新的鸿蒙生态应用开发技术与典型场景结合,让开发者快速地掌握开发高质量应用的方法。同时支持互动式操作,通过文字、代码和效果联动为开发者带来更佳的学习体验。',
      'https://developer.huawei.com/consumer/cn/doc/harmonyos-codelabs/codelabs-0000001443855957'),
    new ArticleClass('5', $r('app.media.enablement_pic5'), 'Sample',
      '面向不同类型的开发者提供的鸿蒙生态应用开发优秀实践,每个Sample Code都是一个可运行的工程,为开发者提供实例化的代码参考。',
      'https://developer.huawei.com/consumer/cn/doc/harmonyos-samples/samples-0000001162414961'),
    new ArticleClass('6', $r('app.media.enablement_pic6'), 'API参考',
      '面向开发者提供鸿蒙系统开放接口的全集,供开发者了解具体接口使用方法。API参考详细地描述了每个接口的功能、使用限制、参数名、参数类型、参数含义、取值范围、权限、注意事项、错误码及返回值等。',
      'https://developer.huawei.com/consumer/cn/doc/harmonyos-references/development-intro-0000001580026066'),
    new ArticleClass('7', $r('app.media.enablement_pic7'), 'FAQ',
      '开发者常见问题的总结,开发者可以通过FAQ更高效地解决常见问题。FAQ会持续刷新,及时呈现最新的常见问题。',
      'https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs/faqs-development-0000001753952202'),
    new ArticleClass('8', $r('app.media.enablement_pic8'), '开发者论坛', '和其他应用开发者交流技术、共同进步。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
  ];
  build() {
    //经过刚刚的分析,我们发现可以使用Column组件来作为外层容器。我们设置Column组件与其上元素的间距为18,设置Column元素的侧轴也就是横向方向上元素的对齐方式为从左至右的布局。
    Column() {
      //我们使用Text组件来加载“赋能套件”的文字。并配置字体进行美观地显示。
      Text('赋能套件')
        .fontColor('#182431')
        .fontSize(16)
        .fontWeight(500)
        .fontFamily('HarmonyHeiTi-medium')
        .textAlign(TextAlign.Start)
        .padding({ left: 16 })
        .margin({ bottom: 8.5 })

      // 使用格子 布局,
      Grid() {
        ForEach(this.enablementList, (item: ArticleClass) => {
          GridItem() {
            EnablementItem({ enablementItem: item })
          }
        }, (item: ArticleClass) => item.id)
      }
      //rowsTemplate和columnsTemplate属性值是一个由多个空格和'数字+fr'间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列宽度。scrollBar用于关闭滚动条。
      // 这里设计真的是一言难尽啊
      .rowsTemplate('1fr')
      .columnsGap(8)
      .scrollBar(BarState.Off)
      .height(169)
      .padding({ top: 2, left: 16, right: 16 })
    }
    .margin({ top: 18 })
    .alignItems(HorizontalAlign.Start)


  }
}

@Preview
@Component
struct TutorialView{
  // 需要解析的数据,放在build上面
  @State tutorialList: Array<ArticleClass> = [
    new ArticleClass('1', $r('app.media.tutorial_pic1'), 'Step1 环境的搭建',
      '本篇教程实现了快速入门——一个用于了解和学习HarmonyOS的应用程序。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('2', $r('app.media.tutorial_pic2'), 'Step2 使用Swiper构建运营广告位',
      'Swiper组件提供滑动轮播显示的能力。Swiper本身是一个容器组件,当设置了多个子组件后,可以对这些子组件进行轮播显示。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('3', $r('app.media.tutorial_pic3'), 'Step3 创建和组合视图',
      'Item定义子组件相关特征。相关组件支持使用条件渲染、循环渲染、懒加载等方式生成子组件。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('4', $r('app.media.tutorial_pic4'), 'Step4 网格和列表组建的使用',
      '网格和列表组件中,当Item达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能,适合用于呈现同类数据类型或数据类型集',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('5', $r('app.media.tutorial_pic5'), 'Step5 应用架构设计基础',
      'ArkUI采取MVVM = Model + View + ViewModel模式,将数据与视图绑定在一起,更新数据的时候直接更新视图。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('6', $r('app.media.tutorial_pic6'), 'Step6 ArkWeb页面适配',
      'ArkWeb(方舟Web)提供了Web组件,用于在应用程序中显示Web页面内容,为开发者提供页面加载、页面交互、页面调试等能力。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('7', $r('app.media.tutorial_pic7'), 'Step7 数据驱动UI更新', '数据更新的同时会直接驱动UI的改变',
      'xxx'),
    new ArticleClass('8', $r('app.media.tutorial_pic8'), 'Step8 设置组件导航',
      'Navigation组件适用于模块内页面切换,一次开发,多端部署场景。通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('9', $r('app.media.tutorial_pic8'), 'Step9 原生智能:AI语音朗读',
      '文本转语音服务提供将文本信息转换为语音并进行播报的能力,便于用户与设备进行互动,实现实时语音交互,文本播报。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('10', $r('app.media.tutorial_pic8'), 'Step10 原生互联:分布式流转',
      '流转能力打破设备界限,多设备联动,使用户应用程序可分可合、可流转,实现如邮件跨设备编辑、多设备协同健身、多屏游戏等分布式业务。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
    new ArticleClass('11', $r('app.media.tutorial_pic8'), 'Step11 一次开发,多端部署',
      '一套代码工程,一次开发上架,多端按需部署。支撑开发者快速高效的开发支持多种终端设备形态的应用,实现对不同设备兼容的同时,提供跨设备的流转、迁移和协同的分布式体验。',
      'https://developer.huawei.com/consumer/cn/forum/home?all=1'),
  ];
  build() {
    Column() {
      //设计入门教程文字
      Text('入门教程')
        .fontColor('#182431')
        .fontSize(16)
        .fontWeight(500)
        .fontFamily('HarmonyHeiTi-medium')
        .textAlign(TextAlign.Start)
        .padding({ left: 16 })
        .margin({ bottom: 8.5 })
      // 使用循环列表,这里显示的List
      List({ space: 12 }) {
        ForEach(this.tutorialList, (item: ArticleClass) => {
          ListItem() {
            // 注意这传入的item,是在TutorialItem里面用@Prop修饰的变量获取
            TutorialItem({ tutorialItem: item })
          }
        }, (item: ArticleClass) => item.id)
      }
      .scrollBar(BarState.Off)
      .padding({ left: 16, right: 16 })
    }
    .margin({ top: 18 })
    .alignItems(HorizontalAlign.Start)
  }
}

一起来看看运行结果

最终的运行结果如下:


可以上下和左右滑动.

完结撒花.有需要源代码的可以留言告诉我一起讨论.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容