玩安卓-鸿蒙版 二 首页横幅、搜刮、跳转链接功能

[复制链接]
发表于 2025-12-2 19:20:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本篇涉及组件TextInput、Image、Menu、Swiper、Web、自界说组件、路由跳转传参、POST哀求


1.首页横幅

Swiper组件内部必要放其他内容组件,且必要设置宽高100%。
Image表现网络图片,直接设置图片链接即可。
  1.       Swiper(){
  2.         ForEach(this.bannerData,(data:Datum,index:number)=>{
  3.           Image(data.imagePath)
  4.             .width('100%')
  5.             .height('100%')
  6.             .onClick(()=>{
  7.               console.log("Swiper onClick link "+data.url)
  8.               router.pushUrl({
  9.                 url:"pages/WebPage",
  10.                 params:{data:data.url}
  11.               })
  12.             })
  13.         })
  14.       }
  15.       .width('100%')
  16.       .height(150)
复制代码
2.搜刮框

placeholder是提示词,text就是输入框已存在的内容,通过onChange监听输入内容。
然后同步bindMenu添加菜单,为了做搜刮热词功能
  1.         TextInput({placeholder:"输入搜索关键词",text:this.searchContent})
  2.           .width(270)
  3.           .height(40)
  4.           .margin({top:10,bottom:10})
  5.           .backgroundColor(Color.White)
  6.           .bindMenu(
  7.             this.searchKey()
  8.           )
  9.           .onChange((value: string) => {
  10.             this.searchContent = value;
  11.           })
复制代码
  1.   @Builder
  2.   searchKey(){
  3.     Menu(){
  4.       ForEach(this.searchKeyData,(data:SearchKeyDataBean,index:number)=>{
  5.         MenuItem({"content":data.name})
  6.           .onClick(()=>{
  7.             this.searchContent = data.name
  8.           })
  9.       })
  10.     }
  11.   }
复制代码
输入完后,点击按钮确认搜刮,跳转到搜刮页。
  1.         Button("搜索")
  2.           .margin({left:10,right:10})
  3.           .onClick(()=>{
  4.             console.log("searchContent "+this.searchContent)
  5.             router.pushUrl({
  6.               url:"pages/SearchListPage",
  7.               params:{data:this.searchContent}
  8.             })
  9.           })
复制代码
3.搜刮页

搜刮页内容就是一个列表,和首页一样,区别是获取搜刮列表是通过POST哀求,必要在method指定post哀求,且在extraData写入post传参
  1.     let httpRequest = http.createHttp();
  2.     httpRequest.request("https://www.wanandroid.com/article/query/"+this.page+"/json", {method: http.RequestMethod.POST,extraData: "k="+this.searchKey,}, (err, data) => {
  3.       if (!err) {
  4.         console.log("SearchListPage data.result:"+data.result.toString())
  5.         let welcome: Welcome = JSON.parse(data.result.toString());
  6.         if(welcome && welcome.data && welcome.data.datas && welcome.data.datas.length > 0){
  7.           this.dataList = this.dataList.concat(welcome.data.datas)
  8.           this.page++;
  9.         }
  10.       } else {
  11.       }
  12.       this.state = RequestState.END;
  13.     })
复制代码
4.列表和横幅都能点击跳转到网页

使用Web组件,传网址给src,controller创建一个默认的即可
  1.       Web({
  2.         src: this.url,
  3.         controller: this.webviewController
  4.       })
复制代码
然后写一个标题栏能返回,能标题栏在搜刮页也要使用,以是做了一个自界说组件,只用@Component形貌
  1. @Component
  2. export struct TitleBar {
  3.   private title = '';
  4.   build() {
  5.     Column() {
  6.       Row() {
  7.         Image($r('app.media.ic_back'))
  8.           .width(20)
  9.           .height(20)
  10.           .margin({ left: 26 })
  11.           .objectFit(ImageFit.Contain)
  12.           .onClick(() => {
  13.             router.back()
  14.           })
  15.           .backgroundColor(Color.Blue)
  16.           .id('backBtn')
  17.         Text(this.title)
  18.           .fontSize(20)
  19.           .layoutWeight(1)
  20.           .margin({ left: 16 })
  21.           .align(Alignment.Start)
  22.         Blank()
  23.       }
  24.       .height(56)
  25.       .width('100%')
  26.     }
  27.   }
  28. }
复制代码
5.完备代码如下:
  1. import { http } from "@kit.NetworkKit";import { DataElement, Welcome } from "../bean/HomePageBean";import { RequestState } from "../data/RequestState";import { router } from "@kit.ArkUI";import { Datum, HomeBannerBean } from "../bean/HomeBannerBean";import { SearchKeyBean, SearchKeyDataBean } from "../bean/SearchKeyBean";@Extend(Column)function ColumnStyle(){  .width("100%")  .borderRadius(24)  .backgroundColor(Color.White)  .padding({left:12,right:12,bottom:4,top:4})}@Componentexport struct HomePage{  @State dataList:DataElement[] = [];  @State bannerData:Datum[] = [];  @State searchKeyData:SearchKeyDataBean[] = [];  @State searchContent:string = ''  aboutToAppear(): void {    this.getHomeData();    this.getHomeBanner();    this.getSearchKey();  }  private page:number = 0;  private state:RequestState = RequestState.INIT;  private lastIndex = 0;  getHomeData(){    this.state = RequestState.REQUESTING;    let httpRequest = http.createHttp();    httpRequest.request("https://www.wanandroid.com/article/list/"+this.page+"/json", {}, (err, data) => {      if (!err) {        console.log("HomePage data.result:"+data.result.toString())        let welcome: Welcome = JSON.parse(data.result.toString());        if(welcome && welcome.data && welcome.data.datas && welcome.data.datas.length > 0){          this.dataList = this.dataList.concat(welcome.data.datas)          this.page++;        }      } else {      }      this.state = RequestState.END;    })  }  getHomeBanner(){    let httpRequest = http.createHttp();    httpRequest.request("https://www.wanandroid.com/banner/json", {}, (err, data) => {      if (!err) {        console.log("HomePage data.result:"+data.result.toString())        let welcome: HomeBannerBean = JSON.parse(data.result.toString());        this.bannerData = welcome.data;      } else {      }      this.state = RequestState.END;    })  }  getSearchKey(){    let httpRequest = http.createHttp();    httpRequest.request("https://www.wanandroid.com/hotkey/json", {}, (err, data) => {      if (!err) {        console.log("HomePage data.result:"+data.result.toString())        let welcome: SearchKeyBean = JSON.parse(data.result.toString());        this.searchKeyData = welcome.data;      } else {      }      this.state = RequestState.END;    })  }
  2.   @Builder
  3.   searchKey(){
  4.     Menu(){
  5.       ForEach(this.searchKeyData,(data:SearchKeyDataBean,index:number)=>{
  6.         MenuItem({"content":data.name})
  7.           .onClick(()=>{
  8.             this.searchContent = data.name
  9.           })
  10.       })
  11.     }
  12.   }  build() {    Column(){      Row(){
  13.         TextInput({placeholder:"输入搜索关键词",text:this.searchContent})
  14.           .width(270)
  15.           .height(40)
  16.           .margin({top:10,bottom:10})
  17.           .backgroundColor(Color.White)
  18.           .bindMenu(
  19.             this.searchKey()
  20.           )
  21.           .onChange((value: string) => {
  22.             this.searchContent = value;
  23.           })
  24.         Button("搜索")
  25.           .margin({left:10,right:10})
  26.           .onClick(()=>{
  27.             console.log("searchContent "+this.searchContent)
  28.             router.pushUrl({
  29.               url:"pages/SearchListPage",
  30.               params:{data:this.searchContent}
  31.             })
  32.           })      }
  33.       Swiper(){
  34.         ForEach(this.bannerData,(data:Datum,index:number)=>{
  35.           Image(data.imagePath)
  36.             .width('100%')
  37.             .height('100%')
  38.             .onClick(()=>{
  39.               console.log("Swiper onClick link "+data.url)
  40.               router.pushUrl({
  41.                 url:"pages/WebPage",
  42.                 params:{data:data.url}
  43.               })
  44.             })
  45.         })
  46.       }
  47.       .width('100%')
  48.       .height(150)      List(){        if(this.dataList){          ForEach(this.dataList,(data:DataElement,index:number)=>{            ListItem(){              Column(){                Text(data.title)                  .height(48)                  .fontSize(14)                  .width('100%')                  .textAlign(TextAlign.Start)                  .fontColor($r('app.color.font_color_shallow'))                  .padding({bottom:4,top:4,left:24})                  .maxLines(1)                Row(){                  Text("分享人:"+data.author+"  分类:"+data.chapterName+"/"+data.superChapterName+"  时间:"+data.publishTime)                    .maxLines(1)                    .fontSize(8)                    .padding({bottom:4,left:24})                }                .width('100%')                .justifyContent(FlexAlign.Start)              }              .ColumnStyle()              .margin({top:6,bottom:6})              .onTouch((event: TouchEvent | undefined) => {                if (event) {                  console.log("event.type "+event.type+" event.y "+event.touches[0].y)                  //判定加载更多,必要当前item展示到末了,而且当前哀求竣事,且往上拉了一段间隔                  if(event.type == TouchType.Up && event.touches[0].y < -100 && this.state == RequestState.END && this.lastIndex == this.dataList.length-1){                    this.getHomeData();                  }                }              })            }.onClick(()=>{              console.log("onClick link "+data.link)              router.pushUrl({                url:"pages/WebPage",                params:{data:data.link}              })            })          })        }      }      .onScrollIndex((start:number,end:number)=>{        //可以获取到当前屏幕第一个可见item和末了一个可见item        console.log("onScrollIndex start "+start+" end "+end)        this.lastIndex = end;      })    }  }}
复制代码
  1. import { http } from "@kit.NetworkKit";import { DataElement, Welcome } from "../bean/HomePageBean";import { RequestState } from "../data/RequestState";import { router } from "@kit.ArkUI";import { TitleBar } from "../view/TitleBar";@Extend(Column)function ColumnStyle(){  .width("100%")  .borderRadius(24)  .backgroundColor(Color.White)  .padding({left:12,right:12,bottom:4,top:4})}@Entry@Componentexport struct SearchListPage{  @State dataList:DataElement[] = [];  searchKey:string = ''  aboutToAppear(): void {    let params: Record<string, Object> = router.getParams() as Record<string, Object>;    this.searchKey = params['data'] as string;    this.getHomeData();  }  private page:number = 0;  private state:RequestState = RequestState.INIT;  private lastIndex = 0;  getHomeData(){    this.state = RequestState.REQUESTING;
  2.     let httpRequest = http.createHttp();
  3.     httpRequest.request("https://www.wanandroid.com/article/query/"+this.page+"/json", {method: http.RequestMethod.POST,extraData: "k="+this.searchKey,}, (err, data) => {
  4.       if (!err) {
  5.         console.log("SearchListPage data.result:"+data.result.toString())
  6.         let welcome: Welcome = JSON.parse(data.result.toString());
  7.         if(welcome && welcome.data && welcome.data.datas && welcome.data.datas.length > 0){
  8.           this.dataList = this.dataList.concat(welcome.data.datas)
  9.           this.page++;
  10.         }
  11.       } else {
  12.       }
  13.       this.state = RequestState.END;
  14.     })  }  build() {    Column(){      TitleBar({title:this.searchKey})      List(){        if(this.dataList){          ForEach(this.dataList,(data:DataElement,index:number)=>{            ListItem(){              Column(){                Text(data.title)                  .height(48)                  .fontSize(14)                  .width('100%')                  .textAlign(TextAlign.Start)                  .fontColor($r('app.color.font_color_shallow'))                  .padding({bottom:4,top:4,left:24})                  .maxLines(1)                Row(){                  Text("分享人:"+data.author+"  分类:"+data.chapterName+"/"+data.superChapterName+"  时间:"+data.publishTime)                    .maxLines(1)                    .fontSize(8)                    .padding({bottom:4,left:24})                }                .width('100%')                .justifyContent(FlexAlign.Start)              }              .ColumnStyle()              .margin({top:6,bottom:6})              .onTouch((event: TouchEvent | undefined) => {                if (event) {                  console.log("event.type "+event.type+" event.y "+event.touches[0].y)                  //判定加载更多,必要当前item展示到末了,而且当前哀求竣事,且往上拉了一段间隔                  if(event.type == TouchType.Up && event.touches[0].y < -100 && this.state == RequestState.END && this.lastIndex == this.dataList.length-1){                    this.getHomeData();                  }                }              })            }.onClick(()=>{              console.log("onClick link "+data.link)              router.pushUrl({                url:"pages/WebPage",                params:{data:data.link}              })            })          })        }      }      .onScrollIndex((start:number,end:number)=>{        //可以获取到当前屏幕第一个可见item和末了一个可见item        console.log("onScrollIndex start "+start+" end "+end)        this.lastIndex = end;      })    }    .backgroundColor($r('app.color.background_shallow_grey'))  }}
复制代码
  1. // renderMode.ets
  2. import { webview } from '@kit.ArkWeb';
  3. import { router } from '@kit.ArkUI';
  4. import { TitleBar } from '../view/TitleBar';
  5. @Entry
  6. @Component
  7. struct WebPage {
  8.   private webviewController: WebviewController = new webview.WebviewController()
  9.   @State url:string = ''
  10.   aboutToAppear() {
  11.     let params: Record<string, Object> = router.getParams() as Record<string, Object>;
  12.     this.url = params['data'] as string;
  13.   }
  14.   build() {
  15.     Column() {
  16.       TitleBar()
  17.       Web({
  18.         src: this.url,
  19.         controller: this.webviewController,
  20.         renderMode: RenderMode.ASYNC_RENDER // 设置渲染模式
  21.       })
  22.         .width('100%')
  23.         .height('100%')
  24.     }
  25.   }
  26. }
复制代码
  1. /* * Copyright (c) 2022-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */import router from '@ohos.router'// Page title bar
  2. @Component
  3. export struct TitleBar {
  4.   private title = '';
  5.   build() {
  6.     Column() {
  7.       Row() {
  8.         Image($r('app.media.ic_back'))
  9.           .width(20)
  10.           .height(20)
  11.           .margin({ left: 26 })
  12.           .objectFit(ImageFit.Contain)
  13.           .onClick(() => {
  14.             router.back()
  15.           })
  16.           .backgroundColor(Color.Blue)
  17.           .id('backBtn')
  18.         Text(this.title)
  19.           .fontSize(20)
  20.           .layoutWeight(1)
  21.           .margin({ left: 16 })
  22.           .align(Alignment.Start)
  23.         Blank()
  24.       }
  25.       .height(56)
  26.       .width('100%')
  27.     }
  28.   }
  29. }
复制代码
  1. export interface HomeBannerBean {
  2.   data:      Datum[];
  3.   errorCode: number;
  4.   errorMsg:  string;
  5. }
  6. export interface Datum {
  7.   desc:      string;
  8.   id:        number;
  9.   imagePath: string;
  10.   isVisible: number;
  11.   order:     number;
  12.   title:     string;
  13.   type:      number;
  14.   url:       string;
  15. }
复制代码
  1. export interface SearchKeyBean {
  2.   data:      SearchKeyDataBean[];
  3.   errorCode: number;
  4.   errorMsg:  string;
  5. }
  6. export interface SearchKeyDataBean {
  7.   id:      number;
  8.   link:    string;
  9.   name:    string;
  10.   order:   number;
  11.   visible: number;
  12. }
复制代码

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表