yangchenggong1_wd

desc:4.0 搜索默认滚动

@@ -169,6 +169,10 @@ export class HttpUrlUtils { @@ -169,6 +169,10 @@ export class HttpUrlUtils {
169 */ 169 */
170 static readonly FOLLOW_OPERATION_PATH: string = "/api/rmrb-interact/interact/zh/c/attention/operation"; 170 static readonly FOLLOW_OPERATION_PATH: string = "/api/rmrb-interact/interact/zh/c/attention/operation";
171 /** 171 /**
  172 + * 首页 搜索提示
  173 + */
  174 + static readonly SEARCH_HINT_DATA_PATH: string = "/api/rmrb-search-api/zh/c/hints";
  175 + /**
172 * 早晚报列表 176 * 早晚报列表
173 * 根据页面id获取页面楼层列表 177 * 根据页面id获取页面楼层列表
174 * https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/pageInfo?pageId=28927 178 * https://pdapis.pdnews.cn/api/rmrb-bff-display-zh/display/zh/c/pageInfo?pageId=28927
@@ -510,6 +514,12 @@ export class HttpUrlUtils { @@ -510,6 +514,12 @@ export class HttpUrlUtils {
510 return url 514 return url
511 } 515 }
512 516
  517 + static getSearchHintDataUrl() {
  518 + let url = HttpUrlUtils._hostUrl + HttpUrlUtils.SEARCH_HINT_DATA_PATH
  519 + return url
  520 + }
  521 +
  522 +
513 523
514 // static getYcgCommonHeaders(): HashMap<string, string> { 524 // static getYcgCommonHeaders(): HashMap<string, string> {
515 // let headers: HashMap<string, string> = new HashMap<string, string>() 525 // let headers: HashMap<string, string> = new HashMap<string, string>()
@@ -58,3 +58,5 @@ export { AudioDetailComponent } from "./src/main/ets/components/AudioDetailCompo @@ -58,3 +58,5 @@ export { AudioDetailComponent } from "./src/main/ets/components/AudioDetailCompo
58 58
59 export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/BroadcastPageComponent" 59 export { BroadcastPageComponent } from "./src/main/ets/components/broadcast/BroadcastPageComponent"
60 60
  61 +export { FirstTabTopSearchComponent } from "./src/main/ets/components/search/FirstTabTopSearchComponent"
  62 +
@@ -3,6 +3,7 @@ import { LazyDataSource, Logger } from 'wdKit'; @@ -3,6 +3,7 @@ import { LazyDataSource, Logger } from 'wdKit';
3 import { WDRouterRule } from 'wdRouter'; 3 import { WDRouterRule } from 'wdRouter';
4 import { PageComponent } from './PageComponent'; 4 import { PageComponent } from './PageComponent';
5 import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout' 5 import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout'
  6 +import { FirstTabTopSearchComponent } from '../search/FirstTabTopSearchComponent';
6 7
7 const TAG = 'TopNavigationComponent'; 8 const TAG = 'TopNavigationComponent';
8 9
@@ -121,38 +122,14 @@ export struct TopNavigationComponent { @@ -121,38 +122,14 @@ export struct TopNavigationComponent {
121 build() { 122 build() {
122 Column() { 123 Column() {
123 // 顶部搜索、日报logo、早晚报 124 // 顶部搜索、日报logo、早晚报
124 - RelativeContainer() {  
125 - Stack({ alignContent: Alignment.Center }) {  
126 -  
127 - Image($r('app.media.background_search'))  
128 - .width('100%')  
129 - .height('100%')  
130 - .objectFit(ImageFit.Contain)  
131 -  
132 - Row() {  
133 - Image($r('app.media.icon_search'))  
134 - .width(18)  
135 - .height(18)  
136 -  
137 - Text('河南大雪')  
138 - .fontColor($r('app.color.color_B0B0B0'))  
139 - .fontSize($r('app.float.font_size_13'))  
140 - }  
141 - .alignItems(VerticalAlign.Center)  
142 - .justifyContent(FlexAlign.Center)  
143 - }  
144 - .height(30)  
145 - .width(123)  
146 - .id('search')  
147 - .alignRules({  
148 - left: { anchor: "__container__", align: HorizontalAlign.Start },  
149 - center: { anchor: "__container__", align: VerticalAlign.Center }  
150 - }) 125 + Column(){
  126 + Row(){
  127 + FirstTabTopSearchComponent()
151 128
152 Image($r('app.media.icon_ren_min_ri_bao')) 129 Image($r('app.media.icon_ren_min_ri_bao'))
153 .width(72) 130 .width(72)
154 .height(29) 131 .height(29)
155 - .onClick(() => { 132 + .onClick((event: ClickEvent) => {
156 let taskAction: Action = { 133 let taskAction: Action = {
157 type: 'JUMP_INNER_NEW_PAGE', 134 type: 'JUMP_INNER_NEW_PAGE',
158 params: { 135 params: {
@@ -161,11 +138,6 @@ export struct TopNavigationComponent { @@ -161,11 +138,6 @@ export struct TopNavigationComponent {
161 }; 138 };
162 WDRouterRule.jumpWithAction(taskAction) 139 WDRouterRule.jumpWithAction(taskAction)
163 }) 140 })
164 - .id('ren_min')  
165 - .alignRules({  
166 - middle: { anchor: "__container__", align: HorizontalAlign.Center },  
167 - center: { anchor: "__container__", align: VerticalAlign.Center }  
168 - })  
169 141
170 Stack({ alignContent: Alignment.Center }) { 142 Stack({ alignContent: Alignment.Center }) {
171 Image($r('app.media.background_read_paper_home')) 143 Image($r('app.media.background_read_paper_home'))
@@ -182,17 +154,10 @@ export struct TopNavigationComponent { @@ -182,17 +154,10 @@ export struct TopNavigationComponent {
182 } 154 }
183 .alignItems(VerticalAlign.Center) 155 .alignItems(VerticalAlign.Center)
184 .justifyContent(FlexAlign.Center) 156 .justifyContent(FlexAlign.Center)
185 -  
186 } 157 }
187 .height(30) 158 .height(30)
188 .width(124) 159 .width(124)
189 - .id('read')  
190 - .alignRules({  
191 - right: { anchor: "__container__", align: HorizontalAlign.End },  
192 - center: { anchor: "__container__", align: VerticalAlign.Center }  
193 - })  
194 .onClick(() => { 160 .onClick(() => {
195 -  
196 let taskAction: Action = { 161 let taskAction: Action = {
197 type: 'JUMP_INNER_NEW_PAGE', 162 type: 'JUMP_INNER_NEW_PAGE',
198 params: { 163 params: {
@@ -201,10 +166,12 @@ export struct TopNavigationComponent { @@ -201,10 +166,12 @@ export struct TopNavigationComponent {
201 }; 166 };
202 WDRouterRule.jumpWithAction(taskAction) 167 WDRouterRule.jumpWithAction(taskAction)
203 }) 168 })
204 - } 169 + }.width('100%')
  170 + .justifyContent(FlexAlign.SpaceBetween)
  171 + }.height('73lpx')
205 .width('100%') 172 .width('100%')
206 - .height(40)  
207 - .visibility(this._currentNavIndex == 0 ? Visibility.Visible : Visibility.None) 173 + .justifyContent(FlexAlign.End)
  174 + .backgroundColor($r('app.color.white'))
208 175
209 // 频道分类list 176 // 频道分类list
210 Stack({ alignContent: Alignment.TopEnd }) { 177 Stack({ alignContent: Alignment.TopEnd }) {
  1 +/**
  2 + * 首页顶部搜索导航栏
  3 + * 竖向滚动实现方案
  4 + * 方案一 使用动画 + 定时器
  5 + * 方案二 使用容器组件Swiper(当前)
  6 + */
  7 +import SearcherAboutDataModel from '../../model/SearcherAboutDataModel'
  8 +
  9 +const TAG = "FirstTabTopSearchComponent"
  10 +@Component
  11 +export struct FirstTabTopSearchComponent{
  12 + @State searchTextData :string[] = []
  13 + private swiperController: SwiperController = new SwiperController()
  14 +
  15 + aboutToAppear(){
  16 + this.getSearchHint()
  17 + }
  18 +
  19 + getSearchHint(){
  20 + SearcherAboutDataModel.getSearchHintData(getContext(this)).then((value)=>{
  21 + if(value!=null){
  22 + this.searchTextData = value
  23 + }
  24 + }).catch((err:Error)=>{
  25 + console.log(TAG,JSON.stringify(err))
  26 + })
  27 + }
  28 +
  29 + build(){
  30 + Row(){
  31 + Image($r('app.media.icon_search'))
  32 + .objectFit(ImageFit.Cover)
  33 + .height('23lpx')
  34 + .width('23lpx')
  35 + .margin({right:'13lpx'})
  36 + .interpolation(ImageInterpolation.Medium)
  37 +
  38 + if(this.searchTextData!=null && this.searchTextData.length>0){
  39 + Swiper(this.swiperController) {
  40 + ForEach(this.searchTextData, (item: string, index: number ) => {
  41 + Text(item)
  42 + .fontWeight('400lpx')
  43 + .fontSize('25lpx')
  44 + .fontColor($r('app.color.color_666666'))
  45 + .lineHeight('35lpx')
  46 + .textAlign(TextAlign.Start)
  47 + .maxLines(1)
  48 + .textOverflow({ overflow: TextOverflow.Clip})
  49 + })
  50 + }
  51 + .loop(true)
  52 + .autoPlay(true)
  53 + .interval(3000)
  54 + .indicator(false)
  55 + .vertical(true)
  56 + }
  57 + }.width('257lpx')
  58 + .height('61lpx')
  59 + .padding({left:'31lpx'})
  60 + .backgroundImage($r('app.media.background_search'))
  61 + .backgroundImageSize(ImageSize.Cover)
  62 + .alignItems(VerticalAlign.Center)
  63 + }
  64 +
  65 +}
  1 +
  2 +import { Logger, ResourcesUtils } from 'wdKit';
  3 +import { HttpUrlUtils, ResponseDTO, WDHttp } from 'wdNetwork';
  4 +import HashMap from '@ohos.util.HashMap';
  5 +const TAG = "SearcherAboutDataModel"
  6 +
  7 +/**
  8 + * 我的页面 所有数据 获取封装类
  9 + */
  10 +class SearcherAboutDataModel{
  11 + private static instance: SearcherAboutDataModel;
  12 +
  13 + private constructor() { }
  14 +
  15 + /**
  16 + * 单例模式
  17 + * @returns
  18 + */
  19 + public static getInstance(): SearcherAboutDataModel {
  20 + if (!SearcherAboutDataModel.instance) {
  21 + SearcherAboutDataModel.instance = new SearcherAboutDataModel();
  22 + }
  23 + return SearcherAboutDataModel.instance;
  24 + }
  25 +
  26 + /**
  27 + * 首页 搜索提示滚动内容
  28 + */
  29 + getSearchHintData(context: Context): Promise<string[]> {
  30 + return new Promise<string[]>((success, error) => {
  31 + Logger.info(TAG, `getSearchHintData start`);
  32 + this.fetchSearchHintData().then((navResDTO: ResponseDTO<string[]>) => {
  33 + if (!navResDTO || navResDTO.code != 0) {
  34 + success(this.getSearchHintDataLocal(context))
  35 + return
  36 + }
  37 + Logger.info(TAG, "getSearchHintData then,SearchHintDataResDTO.timeStamp:" + navResDTO.timestamp);
  38 + let navigationBean = navResDTO.data as string[]
  39 + success(navigationBean);
  40 + }).catch((err: Error) => {
  41 + Logger.error(TAG, `fetchSearchHintData catch, error.name : ${err.name}, error.message:${err.message}`);
  42 + success(this.getSearchHintDataLocal(context))
  43 + })
  44 + })
  45 + }
  46 +
  47 + fetchSearchHintData() {
  48 + let url = HttpUrlUtils.getSearchHintDataUrl()
  49 + let headers: HashMap<string, string> = HttpUrlUtils.getCommonHeaders();
  50 + return WDHttp.get<ResponseDTO<string[]>>(url, headers)
  51 + };
  52 +
  53 + async getSearchHintDataLocal(context: Context): Promise<string[]> {
  54 + Logger.info(TAG, `getSearchHintDataLocal start`);
  55 + let compRes: ResponseDTO<string[]> | null = await ResourcesUtils.getResourcesJson<ResponseDTO<string[]>>(context,'search_hint_data.json' );
  56 + if (!compRes || !compRes.data) {
  57 + Logger.info(TAG, `getSearchHintDataLocal compRes is empty`);
  58 + return []
  59 + }
  60 + Logger.info(TAG, `getSearchHintDataLocal compRes : ${JSON.stringify(compRes)}`);
  61 + return compRes.data
  62 + }
  63 +
  64 +
  65 +
  66 +}
  67 +
  68 +const searcherAboutDataModel = SearcherAboutDataModel.getInstance()
  69 +export default searcherAboutDataModel as SearcherAboutDataModel
  1 +{
  2 + "code": "0",
  3 + "data": [
  4 + "习语",
  5 + "党史学习",
  6 + "高考倒计时"
  7 + ],
  8 + "message": "Success",
  9 + "success": true,
  10 + "timestamp": 1712562841885
  11 +}