接着前面的系列文章,来到了布局更新及新增内容详情查看界面
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、效果图展示
首页最新界面:
内容查看页面:
我的最新界面:
原创不易,求个关注。
微信公众号:一粒尘埃的漫旅
里面有很多想对大家说的话,就像和朋友聊聊天。
写代码,做设计,聊生活,聊工作,聊职场。
我见到的世界是什么样子的?
搜索关注我吧。
公众号与博客的内容不同。