06鸿蒙APP开发之布局优化与完善


接着前面的系列文章,来到了布局更新及新增内容详情查看界面

1、更换数据源

目前发现https的请求无法访问,暂时还不清楚什么原因。
一直报“SSL peer certificate or SSH remote key was not OK”这个错误。
查了一下是证书问题,后续再查查什么问题。

更新TestApiBean,如下:


export class TestApiBean {
  id?:string;
  question?: string;
  correct_answer?: string;
  type?: string;
  title?:string;
  body?:string;

  constructor(
    id:string,
    question: string,
    correct_answer: string,
    type: string,
    title:string,
    body:string
  ) {
    this.id=id;
    this.question = question;
    this.correct_answer = correct_answer;
    this.type = type;
    this.title = title;
    this.body = body;
  }
}

新增 title、body字段。

API返回数据示例:

[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  },

2、主页布局优化

import prompt from '@ohos.promptAction'
import util from '@ohos.util';
//引入自定义类
import { HttpManager } from './net/HttpManager'
import { RequestMethod } from './net/RequestOption';
import { TestApiBean } from './entity/TestApiBean';
import { ResTestAPiBean } from './entity/ResTestAPiBean';
import router from '@ohos.router';

@Entry
@Component
struct Index {
  private tabsController = new TabsController();
  @State index: number = 0; // 选项卡下标,默认为第一个

  //组件Index自带的函数,类似于重写@Override,在build()之前就会执行
  aboutToAppear() {
    this.loadApiTestData();
  }

  //@State此时的状态就非常有用了,当你上下拉刷新UI的时候,只需要重新给此变量赋值就会自动刷新界面(UI),ForEach要求必须Array
  @State testApiBeanList: Array<TestApiBean> = new Array<TestApiBean>();

  /**
   * 调用封装的网络请求类,访问网络API并获取列表数据
   */
  loadApiTestData() {
    HttpManager.getInstance().request<Array<TestApiBean>>({
      url: "http://jsonplaceholder.typicode.com/posts",
      method: RequestMethod.GET,
      header: "application/x-www-form-urlencoded"
    }).then((result) => {

      //循环的去把请求响应回来的数据push(目前只会这种方式,其他的还在了解)到我们创建数据列表对象中
      for (let i = 0; i < result.length; i++) {
        let item = result[i];
        this.testApiBeanList.push({
          // id: util.generateRandomUUID(true),
          id: item.id.toString(),
          title: item.title,
          body: item.body,
        });
      }
    }).catch((error) => {
      console.log(JSON.stringify(error));
    });
  }

  //开始构建UI
  build() {
    Column() {
      Tabs({ controller: this.tabsController }) {
        TabContent() {
          Column() {
            Text("首页")
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
              .fontColor($r("app.color.color_list_title"))
              .margin({ top: 16 })
            Divider().strokeWidth(1).lineCap(LineCapStyle.Square).color("#dddddd").margin({ top: 16 })

            List({ space: 10, initialIndex: 0 }) {
              ForEach(this.testApiBeanList, (item: TestApiBean, index: number) => {
                // 循环渲染ListItem
                ListItem() {
                  Row() {
                    Column() {
                      Text(item.title).fontSize(16).fontColor($r("app.color.color_list_title"))
                      Text(item.body).fontSize(14).fontColor($r("app.color.color_list_abstract"))
                    }.width('100%').alignItems(HorizontalAlign.Start)
                  }.width('100%').justifyContent(FlexAlign.Start).padding({ left: 16, right: 16, top: 8, bottom: 8 })
                  .onClick(() => {
                    //选项单击事件
                    // prompt.showToast({ message: this.testApiBeanList[index].title, duration: 2000 })
                    router.pushUrl({ url: 'pages/ContentDetail', params: item })
                  })
                }
              }, item => item.id)
            }.width("100%").height('100%').listDirection(Axis.Vertical).scrollBar(BarState.Auto)

          }.width('100%').height('100%').backgroundColor("#eeeeee")
        }.tabBar(this.tabHome())

        TabContent() {
          Column() {
            Text("订阅")
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
              .fontColor($r("app.color.color_list_title"))
              .margin({ top: 16 })
            Divider().strokeWidth(1).lineCap(LineCapStyle.Square).color("#dddddd").margin({ top: 16 })
          }.width('100%').height('100%').backgroundColor("#eeeeee")
        }.tabBar(this.tabSub)

        TabContent() {
          Column() {
            Text("我的")
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
              .fontColor($r("app.color.color_list_title"))
              .margin({ top: 16 })
            Divider().strokeWidth(1).lineCap(LineCapStyle.Square).color("#dddddd").margin({ top: 16 })

            Row() {
              Row() {
                Image($r('app.media.ic_car_user')).size({ width: 20, height: 20 }).margin({ right: 5 })
                Text("属性1").fontSize(16).fontColor($r("app.color.color_list_title"))
              }

              Text("Test1").fontSize(16).fontColor($r("app.color.color_list_abstract"))
            }.padding({ top: 16, left: 16, right: 16 }).width('100%').justifyContent(FlexAlign.SpaceBetween)

            Divider()
              .strokeWidth(1)
              .lineCap(LineCapStyle.Square)
              .color("#dddddd")
              .margin({ top: 16, left: 16, right: 16 })

            Row() {
              Row() {
                Image($r('app.media.ic_car_unit')).size({ width: 20, height: 20 }).margin({ right: 5 })
                Text("属性2").fontSize(16).fontColor($r("app.color.color_list_title"))
              }

              Text("Test2").fontSize(16).fontColor($r("app.color.color_list_abstract"))
            }.padding({ top: 16, left: 16, right: 16 }).width('100%').justifyContent(FlexAlign.SpaceBetween)

            Divider()
              .strokeWidth(1)
              .lineCap(LineCapStyle.Round)
              .color("#dddddd")
              .margin({ top: 16, left: 16, right: 16 })

            Row() {
              Row() {
                Image($r('app.media.ic_car_time')).size({ width: 20, height: 20 }).margin({ right: 5 })
                Text("属性3").fontSize(16).fontColor($r("app.color.color_list_title"))
              }

              Text("Test3").fontSize(16).fontColor($r("app.color.color_list_abstract"))
            }.padding({ top: 16, left: 16, right: 16 }).width('100%').justifyContent(FlexAlign.SpaceBetween)

            Divider()
              .strokeWidth(1)
              .lineCap(LineCapStyle.Round)
              .color("#dddddd")
              .margin({ top: 16, left: 16, right: 16 })


            Row() {
              Button("Test", { type: ButtonType.Normal, stateEffect: true })
                .height(45)
                .width('100%')
                .fontColor("#ffffff")
                .fontSize(16)
                .backgroundColor("#ffaaaaaa")
                .borderRadius(8)
                .onClick(() => {
                  prompt.showToast({ message: "click button!", duration: 2000 })
                })
            }.width('100%').margin({ top: 20 }).padding({ left: 16, right: 16 })

          }.width('100%').height('100%').backgroundColor("#eeeeee")
        }.tabBar(this.tabMe)
      }.barPosition(BarPosition.End)
    }.width('100%').height('100%')
  }

  @Builder tabHome() {
    Column() {
      Image(this.index == 0 ? $r('app.media.ic_menu_home_focus') : $r('app.media.ic_menu_home_normal'))
        .size({ width: 25, height: 25 }).margin({ top: 5, bottom: 5 })
      Text("首页").fontSize(16).fontColor(this.index == 0 ? "#2a58d0" : "#6b6b6b")
    }.width('100%').height('100%').onClick(() => {
      this.index = 0;
      this.tabsController.changeIndex(this.index)
    })
  }

  @Builder tabSub() {
    Column() {
      Image(this.index == 1 ? $r('app.media.ic_menu_sub_focus') : $r('app.media.ic_menu_sub_normal'))
        .size({ width: 25, height: 25 }).margin({ top: 5, bottom: 5 })
      Text("订阅").fontSize(16).fontColor(this.index == 1 ? "#2a58d0" : "#6b6b6b")
    }.width('100%').height('100%').onClick(() => {
      this.index = 1;
      this.tabsController.changeIndex(this.index)
    })
  }

  @Builder tabMe() {
    Column() {
      Image(this.index == 2 ? $r('app.media.ic_menu_me_focus') : $r('app.media.ic_menu_me_normal'))
        .size({ width: 25, height: 25 }).margin({ top: 5, bottom: 5 })
      Text("我的").fontSize(16).fontColor(this.index == 2 ? "#2a58d0" : "#6b6b6b")
    }.width('100%').height('100%').onClick(() => {
      this.index = 2;
      this.tabsController.changeIndex(this.index)
    })
  }
}

更换了免费API的url地址,同时更新【我的】菜单内容页面布局,添加标题栏。

添加首页列表项点击跳转页面事件,带参数,代码如下:

 router.pushUrl({ url: 'pages/ContentDetail', params: item })

在ContentDetail.ets接收参数,代码如下:

  @State mBean: TestApiBean = null
  aboutToAppear() {
    this.mBean = router.getParams()
  }

3、新增内容页查看界面

添加ContentDetail.exs,需要在entry\src\main\resources\base\profile\main_pages.json文件中配置页面路径,配置如下所示:

{
  "src": [
    "pages/Index",
    "pages/Login",
    "pages/ContentDetail"
  ]
}

ContentDetail.ets内容如下所示:

import { TestApiBean } from './entity/TestApiBean'
import router from '@ohos.router'

@Entry
@Component
struct ContentDetail {
  @State mBean: TestApiBean = null

  aboutToAppear() {
    this.mBean = router.getParams()
  }

  build() {
    Navigation() {
      Column() {
        Text(Date().toString()).fontSize(14).fontColor($r("app.color.color_list_abstract")).margin({ top: 16 })
        Text(this.mBean.body).fontSize(16).fontColor($r("app.color.color_list_title")).margin({ top: 16 })
      }.width("100%").height("100%").padding({ left: 16, right: 16 }).alignItems(HorizontalAlign.Start)
    }.title(this.mBean.title).titleMode(NavigationTitleMode.Mini)
  }
}

使用router库接收页面传递的对象。

4、效果图展示

首页最新界面:
在这里插入图片描述

内容查看页面:
在这里插入图片描述
我的最新界面:
在这里插入图片描述






原创不易,求个关注。

在这里插入图片描述

微信公众号:一粒尘埃的漫旅
里面有很多想对大家说的话,就像和朋友聊聊天。
写代码,做设计,聊生活,聊工作,聊职场。
我见到的世界是什么样子的?
搜索关注我吧。

公众号与博客的内容不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值