赞
踩
DevEco Studio版本:4.0.0.600
WanAndroid的API链接:玩Android 开放API-玩Android - wanandroid.com
其他篇文章参考:
1、WanAndroid(鸿蒙版)开发的第一篇-CSDN博客
2、WanAndroid(鸿蒙版)开发的第二篇-CSDN博客
从效果图上可以知道整体是竖直方向(Column),包括:搜索框、热搜、搜索历史三个模块
代码实现:
- RelativeContainer() {
- Image($r('app.media.ic_back'))
- .width(32)
- .height(32)
- .id('imageBack')
- .margin({ left: 10, right: 10 })
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- left: { anchor: '__container__', align: HorizontalAlign.Start }
- })
- .onClick(() => {
- router.back()
- })
-
- Button('搜索')
- .height(35)
- .fontColor(Color.White)
- .id('buttonSearch')
- .margin({ left: 10, right: 10 })
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- right: { anchor: '__container__', align: HorizontalAlign.End }
- })
- .linearGradient({
- angle: 0,
- colors: [['#E4572F', 0], ['#D64025', 1]]
- })
- .onClick(() => {
- if (this.searchContent.trim().length > 0) {
- this.insertData(new SearchContentBean(this.searchContent.trim()))
- this.jumpToSearchDetails(this.searchContent)
- } else {
- promptAction.showToast({ message: '搜索内容为空' })
- }
- })
-
- Row() {
- Image($r('app.media.ic_search_8a8a8a'))
- .width(20)
- .height(20)
- TextInput({ placeholder: '发现更多干货', text: '鸿洋' })
- .fontSize(16)
- .backgroundColor('#00000000')
- .enterKeyType(EnterKeyType.Search)
- .width('100%')
- .height(45)
- .flexShrink(1)
- .onChange((value: string) => {
- this.searchContent = value
- })
- }
- .height(45)
- .padding(5)
- .borderWidth(1)
- .borderColor('#ED7C12')
- .borderRadius(10)
- .id('rowSearch')
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- left: { anchor: 'imageBack', align: HorizontalAlign.End },
- right: { anchor: 'buttonSearch', align: HorizontalAlign.Start }
- })
- }
- .width('100%')
- .height(70)
从UI效果上可以看出热搜内容是个流式布局,要实现流式布局可以通过
Flex({ justifyContent: FlexAlign.Start, wrap: FlexWrap.Wrap }) 来实现
代码实现:
- @Component
- export struct FlowlayoutView {
- @Link flowlayoutArr: string[]
- private onItemClick: (item: string, index: number) => void = () => {
- }
-
- build() {
- // Flex布局, wrap为FlexWrap.Wrap为流式布局
- Flex({ justifyContent: FlexAlign.Start, wrap: FlexWrap.Wrap }) {
- if (this.flowlayoutArr.length > 0) {
- ForEach(this.flowlayoutArr,
- (item: string, index: number) => {
- Text(`${item}`)
- .fontSize(18)
- .fontColor(Color.White)
- .borderStyle(BorderStyle.Solid)
- .padding({ left: 10, right: 10, top: 6, bottom: 6 })
- .backgroundColor(Color.Pink)
- .borderRadius(5)
- .margin({ top: 10, right: 10 })
- .textOverflow({ overflow: TextOverflow.Ellipsis })
- .maxLines(2)
- .onClick(() => {
- this.onItemClick(item, index)
- })
- },
- (item: string) => item.toString()
- )
- }
- }
- }
- }
每次点击搜索或点击热搜中的关键词时,将点击的内容保存到数据库中,在搜索页面显示时(onPageShow)去查询数据库。UI上通过List去加载查询的数据
数据库实现:
参考BaseLibrary 中database里面的代码
代码实现:
- List() {
- ForEach(this.searchHistoryList, (item, index) => {
- ListItem() {
- Row() {
- Image($r('app.media.searchHistory'))
- .width(24)
- .height(24)
- .margin({ left: 20 })
- Text(item)
- .fontColor(this.getTextColor(index))
- .fontSize(20)
- .margin({ right: 20 })
- }.width('100%')
- .padding({ top: 15, bottom: 15 })
- .justifyContent(FlexAlign.SpaceBetween)
- }.swipeAction({ end: this.itemEnd(index) })
- .onClick(() => {
- this.jumpToSearchDetails(item)
- })
- })
- }
- .flexShrink(1)
- .width('100%')
- .height('100%')
- import router from '@ohos.router'
- import promptAction from '@ohos.promptAction'
- import { FlowlayoutView, HttpManager, RequestMethod, SearchContentBean, SQLManager } from '@app/BaseLibrary'
- import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils'
- import { SearchHotKey } from '../../bean/search/SearchHotKeyBean'
-
- const TAG = 'SearchPage--- ';
-
- @Entry
- @Component
- struct SearchPage {
- private sqlManager = new SQLManager();
- @State searchContent: string = ''
- @State searchHotKeyArr: string[] = []
- @State searchHistoryList: string[] = []
- @State searchContentBeanList: SearchContentBean[] = []
-
- aboutToAppear() {
- this.getSearchHotKeyData()
- }
-
- onPageShow() {
- this.queryAllData()
- }
-
- private getSearchHotKeyData() {
- HttpManager.getInstance()
- .request<SearchHotKey>({
- method: RequestMethod.GET,
- url: `https://www.wanandroid.com/hotkey/json`, //wanAndroid的API:搜索热词
- })
- .then((result: SearchHotKey) => {
- LogUtils.info(TAG, "result: " + JSON.stringify(result))
- if (result.errorCode == 0) {
- for (let i = 0; i < result.data.length; i++) {
- this.searchHotKeyArr = this.searchHotKeyArr.concat(result.data[i].name)
- }
- }
- LogUtils.info(TAG, "添加后的searchHotKeyArr: " + JSON.stringify(this.searchHotKeyArr))
- })
- .catch((error) => {
- LogUtils.info(TAG, "error: " + JSON.stringify(error))
- })
- }
-
- build() {
- Column() {
- RelativeContainer() {
- Image($r('app.media.ic_back'))
- .width(32)
- .height(32)
- .id('imageBack')
- .margin({ left: 10, right: 10 })
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- left: { anchor: '__container__', align: HorizontalAlign.Start }
- })
- .onClick(() => {
- router.back()
- })
-
- Button('搜索')
- .height(35)
- .fontColor(Color.White)
- .id('buttonSearch')
- .margin({ left: 10, right: 10 })
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- right: { anchor: '__container__', align: HorizontalAlign.End }
- })
- .linearGradient({
- angle: 0,
- colors: [['#E4572F', 0], ['#D64025', 1]]
- })
- .onClick(() => {
- if (this.searchContent.trim().length > 0) {
- this.insertData(new SearchContentBean(this.searchContent.trim()))
- this.jumpToSearchDetails(this.searchContent)
- } else {
- promptAction.showToast({ message: '搜索内容为空' })
- }
- })
-
- Row() {
- Image($r('app.media.ic_search_8a8a8a'))
- .width(20)
- .height(20)
- TextInput({ placeholder: '发现更多干货', text: '鸿洋' })
- .fontSize(16)
- .backgroundColor('#00000000')
- .enterKeyType(EnterKeyType.Search)
- .width('100%')
- .height(45)
- .flexShrink(1)
- .onChange((value: string) => {
- this.searchContent = value
- })
- }
- .height(45)
- .padding(5)
- .borderWidth(1)
- .borderColor('#ED7C12')
- .borderRadius(10)
- .id('rowSearch')
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- left: { anchor: 'imageBack', align: HorizontalAlign.End },
- right: { anchor: 'buttonSearch', align: HorizontalAlign.Start }
- })
- }
- .width('100%')
- .height(70)
-
- Divider().strokeWidth(1).color('#F1F3F5')
-
- Text('热搜')
- .fontSize(20)
- .fontColor('#D64025')
- .margin({ left: 15, right: 15, top: 10 })
- .alignSelf(ItemAlign.Start)
-
- //自定义流式布局
- FlowlayoutView({
- flowlayoutArr: this.searchHotKeyArr,
- onItemClick: (item, index) => {
- LogUtils.info(TAG, "Index------ 点击了:index: " + index + " item: " + item)
- this.insertData(new SearchContentBean(item))
- this.jumpToSearchDetails(item)
- }
- }).margin({ left: 20, right: 20 })
-
- Row() {
- Text('搜索历史')
- .fontSize(20)
- .fontColor('#1296db')
- .margin({ left: 15, right: 15, top: 15, bottom: 15 })
- .alignSelf(ItemAlign.Start)
-
- Row() {
- Image($r('app.media.deleteAll'))
- .width(22)
- .height(22)
- Text('清空')
- .fontColor(Color.Black)
- .margin({ left: 5 })
- .fontSize(20)
- }.margin({ left: 15, right: 15, top: 15, bottom: 15 })
- .onClick(() => {
- this.deleteAllData()
- })
- }
- .width('100%')
- .justifyContent(FlexAlign.SpaceBetween)
-
- List() {
- ForEach(this.searchHistoryList, (item, index) => {
- ListItem() {
- Row() {
- Image($r('app.media.searchHistory'))
- .width(24)
- .height(24)
- .margin({ left: 20 })
- Text(item)
- .fontColor(this.getTextColor(index))
- .fontSize(20)
- .margin({ right: 20 })
- }.width('100%')
- .padding({ top: 15, bottom: 15 })
- .justifyContent(FlexAlign.SpaceBetween)
- }.swipeAction({ end: this.itemEnd(index) })
- .onClick(() => {
- this.jumpToSearchDetails(item)
- })
- })
- }
- .flexShrink(1)
- .width('100%')
- .height('100%')
- }
- .width('100%')
- .height('100%')
- .backgroundColor(Color.White)
- }
-
- @Builder
- itemEnd(index: number) { // 侧滑后尾端出现的组件
- Image($r('app.media.deleteAll'))
- .width(30)
- .height(30)
- .margin(10)
- .onClick(() => {
- this.deleteData(this.searchContentBeanList[index])
- this.searchHistoryList.splice(index, 1);
- this.searchContentBeanList.splice(index, 1);
- })
- }
-
- /**
- * 跳转到搜索详情页
- */
- private jumpToSearchDetails(content: string) {
- router.pushUrl({
- url: 'pages/search/SearchDetailsPage',
- params: {
- searchContent: content
- }
- }, router.RouterMode.Single)
- }
-
- private deleteData(searchContentBean: SearchContentBean) {
- LogUtils.info("Rdb----- deleteData result: " + searchContentBean.id + " searchContent: " + searchContentBean.searchContent)
- this.sqlManager.deleteData(searchContentBean, (result) => {
- LogUtils.info("Rdb----- 删除 result: " + result)
- })
- }
-
- /**
- * 删除所有数据
- */
- private deleteAllData() {
- if (this.searchHistoryList.length <= 0) {
- promptAction.showToast({ message: '没有可清除的数据' })
- return
- }
- this.sqlManager.deleteDataAll((result) => {
- LogUtils.info(TAG, "Rdb----- 删除所有 result: " + result)
- if (result) {
- promptAction.showToast({ message: '清除完成' })
- this.searchHistoryList = []
- }
- })
- }
-
- /**
- * 查询所有数据
- */
- private queryAllData() {
- this.sqlManager.getRdbStore(() => {
- this.sqlManager.query((result: Array<SearchContentBean>) => {
- LogUtils.info(TAG, "Rdb----- 查询 result: " + JSON.stringify(result))
- this.searchContentBeanList = result
- this.searchHistoryList = []
- for (let i = 0; i < result.length; i++) {
- this.searchHistoryList.push(result[i].searchContent)
- }
- })
- })
- }
-
- /**
- * 插入数据
- */
- private insertData(searchContentBean: SearchContentBean) {
- this.sqlManager.insertData(searchContentBean, (id: number) => {
- LogUtils.info(TAG, "Rdb----- result 插入 id: " + id)
- searchContentBean.id = id
- if (id >= 0) { //id < 0 表示插入数据失败
- }
- })
- }
-
- private getTextColor(index: number): ResourceColor {
- if (index % 3 == 0) {
- return Color.Orange
- } else if (index % 3 == 1) {
- return Color.Blue
- } else if (index % 3 == 2) {
- return Color.Pink
- }
- return Color.Black
- }
- }
代码实现:
- import router from '@ohos.router';
- import {
- Constants,
- HtmlUtils,
- HttpManager,
- LoadingDialog,
- RefreshController,
- RefreshListView,
- RequestMethod
- } from '@app/BaseLibrary';
- import LogUtils from '@app/BaseLibrary/src/main/ets/utils/LogUtils';
- import { SearchDetailsItemBean } from '../../bean/search/SearchDetailsItemBean';
- import { SearchDetailsBean } from '../../bean/search/SearchDetailsBean';
- import promptAction from '@ohos.promptAction';
- import { AppTitleBar } from '../../widget/AppTitleBar';
-
- const TAG = 'SearchDetailsPage--- ';
-
- @Entry
- @Component
- struct SearchDetailsPage {
- @State searchContent: string = router.getParams()?.['searchContent'];
- @State controller: RefreshController = new RefreshController()
- @State searchDetailsListData: Array<SearchDetailsItemBean> = [];
- @State pageNum: number = 0
- @State isRefresh: boolean = true
- @State userName: string = ''
- @State token_pass: string = ''
-
- aboutToAppear() {
- LogUtils.info(TAG, " aboutToAppear: " + this.searchContent)
- if (AppStorage.Has(Constants.APPSTORAGE_USERNAME)) {
- this.userName = AppStorage.Get(Constants.APPSTORAGE_USERNAME) as string
- }
- if (AppStorage.Has(Constants.APPSTORAGE_TOKEN_PASS)) {
- this.token_pass = AppStorage.Get(Constants.APPSTORAGE_TOKEN_PASS) as string
- }
- this.dialogController.open()
- this.getSearchDetailsData()
- }
-
- private getSearchDetailsData() {
- HttpManager.getInstance()
- .request<SearchDetailsBean>({
- method: RequestMethod.POST,
- header: {
- "Content-Type": "application/json",
- "Cookie": `loginUserName=${this.userName}; token_pass=${this.token_pass}`
- },
- url: `https://www.wanandroid.com/article/query/${this.pageNum}/json/?k=${encodeURIComponent(this.searchContent)}`, //wanAndroid的API:搜索 ?k=${this.searchContent}
- })
- .then((result: SearchDetailsBean) => {
- LogUtils.info(TAG, "result: " + JSON.stringify(result))
- if (this.isRefresh) {
- this.controller.finishRefresh()
- } else {
- this.controller.finishLoadMore()
- }
- if (result.errorCode == 0) {
- if (this.isRefresh) {
- this.searchDetailsListData = result.data.datas
- } else {
- if (result.data.datas.length > 0) {
- this.searchDetailsListData = this.searchDetailsListData.concat(result.data.datas)
- } else {
- promptAction.showToast({ message: '没有更多数据啦!' })
- }
- }
- }
- this.dialogController.close()
- })
- .catch((error) => {
- LogUtils.info(TAG, "error: " + JSON.stringify(error))
- if (this.isRefresh) {
- this.controller.finishRefresh()
- } else {
- this.controller.finishLoadMore()
- }
- this.dialogController.close()
- })
- }
-
- build() {
- Column() {
- AppTitleBar({ title: this.searchContent })
-
- RefreshListView({
- list: this.searchDetailsListData,
- controller: this.controller,
- isEnableLog: true,
- paddingRefresh: { left: 10, right: 10, top: 5, bottom: 5 },
- refreshLayout: (item: SearchDetailsItemBean, index: number): void => this.itemLayout(item, index),
- onItemClick: (item: SearchDetailsItemBean, index: number) => {
- LogUtils.info(TAG, "点击了:index: " + index + " item: " + item)
- router.pushUrl({
- url: 'pages/WebPage',
- params: {
- title: item.title,
- uriLink: item.link
- }
- }, router.RouterMode.Single)
- },
- onRefresh: () => {
- //下拉刷新
- this.isRefresh = true
- this.pageNum = 0
- this.getSearchDetailsData()
- },
- onLoadMore: () => {
- //上拉加载
- this.isRefresh = false
- this.pageNum++
- this.getSearchDetailsData()
- }
- }).flexShrink(1)
-
- }
- .width('100%')
- .height('100%')
- .backgroundColor('#F1F3F5')
- }
-
- @Builder
- itemLayout(item: SearchDetailsItemBean, index: number) {
- RelativeContainer() {
- //作者或分享人
- Text(item.author.length > 0 ? "作者:" + item.author : "分享人:" + item.shareUser)
- .fontColor('#666666')
- .fontSize(14)
- .id("textAuthor")
- .alignRules({
- top: { anchor: '__container__', align: VerticalAlign.Top },
- left: { anchor: '__container__', align: HorizontalAlign.Start }
- })
-
- Text(item.superChapterName + '/' + item.chapterName)
- .fontColor('#1296db')
- .fontSize(14)
- .id("textChapterName")
- .alignRules({
- top: { anchor: '__container__', align: VerticalAlign.Top },
- right: { anchor: '__container__', align: HorizontalAlign.End }
- })
-
- //标题
- Text(HtmlUtils.formatStr(item.title))
- .fontColor('#333333')
- .fontWeight(FontWeight.Bold)
- .maxLines(2)
- .textOverflow({
- overflow: TextOverflow.Ellipsis
- })
- .fontSize(20)
- .margin({ top: 10 })
- .id("textTitle")
- .alignRules({
- top: { anchor: 'textAuthor', align: VerticalAlign.Bottom },
- left: { anchor: '__container__', align: HorizontalAlign.Start }
- })
-
- //更新时间
- Text("时间:" + item.niceDate)
- .fontColor('#666666')
- .fontSize(14)
- .id("textNiceDate")
- .alignRules({
- bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
- left: { anchor: '__container__', align: HorizontalAlign.Start }
- })
- }
- .width('100%')
- .height(120)
- .padding(10)
- .borderRadius(10)
- .backgroundColor(Color.White)
- }
-
- private dialogController = new CustomDialogController({
- builder: LoadingDialog(),
- customStyle: true,
- alignment: DialogAlignment.Center, // 可设置dialog的对齐方式,设定显示在底部或中间等,默认为底部显示
- })
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。