当前位置: 首页 > news >正文

建站工具推荐三合一网站建设 万网

建站工具推荐,三合一网站建设 万网,建设网站计划ppt模板,龙岩平面设计背景 几乎每家应用中都带有搜索功能#xff0c;关于这个功能的页面不是特别复杂#xff0c;但如果要追究其背后的一系列逻辑#xff0c;可能是整个应用中最复杂的一个功能。今天主要实践目标#xff0c;会抛开复杂的逻辑#xff0c;尝试纯粹实现一个“搜索主页”#xf…背景 几乎每家应用中都带有搜索功能关于这个功能的页面不是特别复杂但如果要追究其背后的一系列逻辑可能是整个应用中最复杂的一个功能。今天主要实践目标会抛开复杂的逻辑尝试纯粹实现一个“搜索主页”主要包含输入框文字输入热门词展示热门帖子展示。全篇主要使用到的控件是TextInput, Flex, Swiper。为了贴近实战文字输入过程中也增加了联想词功能。整个示例将在模拟状态下完成不做任何网络请求。 功能清单 输入框 - TextInput用法按钮搜索词删除 - 触摸事件透传用法搜索按钮 - 页面返回用法联想词 - Span用法if...else 渲染用法历史搜索词 - 行数限制排序热门搜索词 - 换行布局行为识别打开链接发起搜索热门帖子 - Swiper用法Span用法 效果 布局结构 整体页面分为上下布局两大部分: 搜索栏可滚动内容区域 开始前熟悉鸿蒙文档 鸿蒙OS开发更多内容↓点击HarmonyOS与OpenHarmony技术鸿蒙技术文档《鸿蒙NEXT星河版开发学习文档》 搜索框 HarmonyOS 提供了Search控件, 这种样式不太满足今天要做的需求所以我还是准备采用TextInput控件重新定制 预期的搜索框需要包含基础的三个功能 文字输入文字删除提交已输入的文字即准备发起搜索 这个样式的实现方式我采用了左右布局左布局采用叠加布局方式翻译为代码表现形式如下 //一. 左布局输入框 右布局搜索按钮 Row() {Stack() {// 输入框TextInput(// 放大镜图片 删除按钮图片 Row() {Image(放大镜图片)if (this.currentInputBoxContent.length ! 0) {Image(删除按钮图片)}}//搜索按钮 / 返回按钮Text(this.searchButtonText) } 这里的Stack布局方式实际中会引发一个问题点击TextInput控件时非常不灵敏实际情况是“放大镜图片删除按钮图解片”Row布局消耗了输入框的触摸事件。 解决这个问题可以使用系统提供的hitTestBehavior(HitTestMode.None)这个接口这个接口的参数提供了4种响应触摸事件的功能 所以解决此问题只需要添加完这个接口即可恢复正常触摸事件见代码中的 NOTE:父组件不消耗触摸事件 //一. 左布局输入框 右布局搜索按钮 Row() {Stack() {// 输入框TextInput(// 放大镜图片 删除按钮图片 Row() {Image(放大镜图片)if (this.currentInputBoxContent.length ! 0) {Image(删除按钮图片)}.hitTestBehavior(HitTestMode.None) // NOTE父组件不消耗触摸事件}//搜索按钮 / 返回按钮Text(this.searchButtonText) } 由于采用的是Stack叠加布局方式所以要解决的第二个问题是如何将Row布局两边对齐Stack即处于TextInput控件的两端根据[Row容器内子元素在水平方向上的排列]可知在Row布局上添加justifyContent(FlexAlign.SpaceBetween)这句代码即可。 官方指导示意图 变更后的代码 //一. 左布局输入框 右布局搜索按钮 Row() {Stack() {// 输入框TextInput(// 放大镜图片 删除按钮图片 Row() {Image(放大镜图片)if (this.currentInputBoxContent.length ! 0) {Image(删除按钮图片)}.hitTestBehavior(HitTestMode.None) // NOTE父组件不消耗触摸事件.justifyContent(FlexAlign.SpaceBetween) // NOTE: 两端对齐}//搜索按钮 / 返回按钮Text(this.searchButtonText) } TextInput的构造函数参数说明 placeholder: 俗称按提示提示词引导词text: 输入框已输入的文字内容 TextInput的属性方法onChange 用来监听最新已输入的文字 这个方法中我们可以通过判断内容长度来设置控制中的搜索按钮文字如果有内容按钮文案将变为搜索反之按钮文案变为“取消”即点击之后将关闭当前页面 同时请求远端联想词的功能也是在这里触发注意本篇文章中的联想词仅仅是本地模拟的数据没有进行网络请求也没有模拟网络延时加载在真实场景中一定要注意用户的操作行为应该中断本次联想词的网络请求即使网络请求已经发出去回来之后也要扔掉拿到的联想词数据。 TextInput的属性方法enterKeyType 这个用来修改软件盘上的回车键文字提示这个设置的值为EnterKeyType.Search,所以在中文模式下你会发现键盘上的文字为搜索 TextInput({ placeholder: 热词搜索, text: this.currentInputBoxContent }).height(40vp).fontSize(20fp).enterKeyType(EnterKeyType.Search).placeholderColor(Color.Grey).placeholderFont({ size: 14vp, weight: 400 }).width(100%).padding({ left: 35vp, right: 35vp }).borderStyle(BorderStyle.Solid).borderWidth(1vp).borderColor(Color.Red).onChange((currentContent) {this.currentInputBoxContent currentContentif (this.currentInputBoxContent.length ! 0) {this.searchButtonText 搜索this.showThinkWord truethis.simulatorThinkWord()} else {this.searchButtonText 取消this.showThinkWord false}}).onSubmit((enterKey: EnterKeyType) {this.submitData(new HistoryWordModel(0, this.currentInputBoxContent));}) 至此一个完整的输入框已完美的完成布局。 历史搜索词 一个搜索的新手产品在讲解这部分需求时会使用简短的话术把搜索过的内容显示出来。 实际情况是比较严谨复杂的最多多展示多少行 每个历史词最多展示多少个字符 要不要识别词性......, 针对这些严格的逻辑研发人员需要优先解决动态布局的问题剩下的仅仅是堆积代码。 在Android系统中针对这种布局场景需要代码动态实现即采用Java方式布局不幸的是HarmonyOS 中没有这个说法。 解决方案 给历史词变量添加 State 修饰根据视图高度动态计算行数然后动态删除多余关键词记录 注意State 修饰的Array无法对sort方法生效结合场景描述即最新搜索的关键词都要排在第一个位置所以每发起一次搜索都要对Array类型的变量进行一次排序由于State的限制我们需要在中间中转一次。 既然已经知道问题那么先看一下布局代码然后继续完成需求 首先对动态布局的需求来讲HarmonyOS中貌似只能用Flex容器来解决因为它不仅可以包含子组件也有自动换行功能所这里我采用的是Flex容器如果你要更好的方案欢迎留言交流 通过视图高度动态计算行数可以依赖onAreaChange接口在其回调中通过每次的新值结构体即Area,获取当前布局高度然后除以第一次获取到的高度这样即可完成行数的测算 关于Flex自动换行功能这个要依赖于一个参数wrap: FlexWrap.Wrap if (this.historyWords.length ! 0) {Row() {Text(历史搜索).fontSize(20fp).fontWeight(FontWeight.Bold)Image($r(app.media.ic_public_delete)).width(20vp).height(20vp).onClick(() {this.dialogController.open()})}.width(100%).margin({ top: 20vp }).padding({ left: 10vp, right: 10vp }).justifyContent(FlexAlign.SpaceBetween)Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {ForEach(this.historyWords, (item: HistoryWordModel, index) {Text(item.word).fontSize(15).margin(5).fontColor(#5d5d5d).maxLines(1).backgroundColor(#f6f6f6).padding({ left: 20, right: 20, top: 5, bottom: 5 }).borderRadius(30vp).textOverflow({ overflow: TextOverflow.Ellipsis }).onClick((){this.submitData(item);})})}.width(100%).margin({ top: 12vp }).onAreaChange((oldValue: Area, newValue: Area) {let newHeight newValue.height as number//全局声明一个历史词单行高度变量初始值设置为0一旦产生历史词将行高设置为此值//后续将以此值为标准来计算历史词行数if(this.currentHistoryHeight 0){this.currentHistoryHeight newHeight}//这里仅仅取整this.currentLineNumbs newHeight / this.currentHistoryHeight//MAX_LINES 代表最大行数if (this.currentLineNumbs MAX_LINES) {//删除一个历史词由于historyWords添加了State修饰所以数据发生变化后页面会刷新//页面刷新后又会重新触发此方法this.historyWords this.historyWords.slice(0, this.historyWords.length-1)}})} 刚刚提到过一个问题State 修饰的Array变量是无法进行排序的。应对这个问题可以在中间中转一下即声明一个局部Array先将历史记录赋值给它让这个局部Array参与sort然后清空State修饰的Array变量最终将局部Array赋值给State修饰的Array变量描述有点繁琐直接看代码。 只要发起搜索行为都会使用到此方法 另外注意阅读代码注释有NOTE的文字 submitData(wordModel: HistoryWordModel) {if (wordModel.word.length ! 0) {//标识本次搜索的关键词是否存在let exist: boolean false//如果搜索关键词存在记录其位置如果发现其已经是第一个位置则不进行排序刷新动作let existIndex: number -1//判断搜索关键是否存在于历史搜索词列表中this.historyWords.forEach((item, index) {if(item.word wordModel.word){//如果本次搜索关键词已经处于历史搜索词的第一个位置不做删除动作if(index ! 0){//如果存在先删除历史词列表中的这个关键词this.historyWords.splice(index, 1)}exist trueexistIndex index}});//本次搜索关键词在历史搜索词列表中处于第一个位置因此不做任何额外处理//NOTE真实场景中这里除了重置状态应该发起网络请求if(existIndex 0){console.log(不需要刷新页面)this.currentInputBoxContent this.searchButtonText 取消this.showThinkWord falsereturn}if(!exist){//如果本次搜索关键词在历史词列表中不存在则将其加入其中wordModel.index this.historyWordIndexthis.historyWords.push(wordModel)} else {//如果本次搜索关键词已存在于历史词列表中将其对应的下标加1因为后续会用下表排序//下标越大代表离发生过的搜索行为离当前越近this.historyWordIndexthis.historyWords.push(new HistoryWordModel(this.historyWordIndex, wordModel.word, wordModel.link))}//NOTE这个就是中转排序的起始代码let Test: ArrayHistoryWordModel []this.historyWords.forEach((item, index) {Test.push(item)})Test.sort((a:HistoryWordModel, b:HistoryWordModel) {return b.index - a.index})this.historyWords.length 0Test.forEach((item, index) {this.historyWords.push(item)})//NOTE这个就是中转排序的结束代码this.currentInputBoxContent this.searchButtonText 取消this.showThinkWord false} else {Prompt.showToast({message: 请输入关键词,bottom: px2vp(this.toastBottom)})} } 至此历史记录也实现完成。 联想词实现 在已有的搜索场景中我们都知道当发起联想词时历史搜索记录热词等等均不会出现在当前屏幕中为了实现此种效果我采用了Stack控件叠加覆盖机制和if...else渲染机制最终实现完成之后发现没必要使用Stack控件因为用了if...else布局后像当于会动态挂载和卸载试图。 联想词实现还会碰到的一个问题高亮关键词 按照HarmonyOS 的布局机制一切布局都应该提前计算好全量布局多种场景样式以if...else机制为基础完整最终的业务场景效果。 那么如何提前计算好数据呢高亮词在数据结构上我们可以分为三段前中后。如何理解呢比如搜索关键词“1”那我的联想词无非就几种情况1232131231那么我声明三个变量s, m, e, 分别代表前中后此时你会发现三个变量是完全可以覆盖所有的匹配场景的。这种方式暂且命名为分割“分割”后在最终展示时由于需要高亮文字所以我们还需要知晓已“分割”的文字中到底哪一段应该高亮基于此种考虑需要额外声明高亮下标参考“前中后”将下标分别定义为012 具体实现看代码吧 Stack() {//联想词需要展示时if (this.showThinkWord) {Column() {//遍历联想词ForEach(this.thinkWords, (item: ThinkWordModel, index) {//NOTE: Span控件可以实现文字分段多种样式Text() {//判断一条联想词数据的“前”if (item.wordStart item.wordStart.length ! 0) {Span(item.wordStart).fontSize(18).fontColor(item.highLightIndex 0 ? item.highLightColor : item.normalColor)}//判断一条联想词数据的“中”if (item.wordMid item.wordMid.length ! 0) {Span(item.wordMid).fontSize(18).fontColor(item.highLightIndex 1 ? item.highLightColor : item.normalColor)}//判断一条联想词数据的“后”if (item.wordEnd item.wordEnd.length ! 0) {Span(item.wordEnd).fontSize(18).fontColor(item.highLightIndex 2 ? item.highLightColor : item.normalColor)}}......})}......} else {// 没有联想词时系统机制会讲联想词视图卸载掉即if中的视图会完全从视图节点中拿掉Column() {//二. 搜索历史if (this.historyWords.length ! 0) {......}//三. 热门搜索Text(热门搜索)......Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {ForEach(this.hotWords, (item: HotWordsModel, index) {Text(item.word)......})}//四. 热门帖子Text(热门帖子)Swiper(this.swiperController) {LazyForEach(this.data, (item: string, index: number) {......}, item item)}}}} 热门帖子实现 在整个搜索主页中这个功能可能算比较简单的在Scroll控件中放置Swiper控件然后按照官方文档循环塞入数据整个效果即可实现。 这个里边用到了Span由于我们在联想词实现时已经实践过了Span, 这里就不再描述。 NOTE为了迎合需求将滑动指示隐藏掉indicator(false)false代表隐藏滑动指示 //四. 热门帖子 Text(热门帖子).fontSize(20fp).width(100%).fontWeight(FontWeight.Bold).margin({ left: 10vp, top: 20vp })Swiper(this.swiperController) {//data仅仅是为了循环数据总个数是3 LazyForEach(this.data, (item: string, index: number) {//每一页Swiper内容视图通过 Builder 修饰的方法进行一次封装if (index 0) {this.swiperList(this.hotTopicList1)} else if (index 1) {this.swiperList(this.hotTopicList2)} else if (index 2) {this.swiperList(this.hotTopicList3)}}, item item)} .padding({ bottom: 50vp }) .displayMode(SwiperDisplayMode.AutoLinear) .margin({ top: 12vp }) .cachedCount(2) .index(1) .indicator(false) .loop(true) .itemSpace(0) .curve(Curve.Linear)完整代码 主页面代码 SearchUI.ets import common from ohos.app.ability.common; import Prompt from system.prompt; import router from ohos.router; import dataPreferences from ohos.data.preferences;import { CommonConstants } from ../../common/CommonConstants; import HotWordsModel from ../../viewmodel/HotWordsModel; import mediaquery from ohos.mediaquery; import ThinkWordModel from ../../viewmodel/ThinkWordModel; import HistoryWordModel from ../../viewmodel/HistoryWordModel;const MAX_LINES: number 3;Entry Component struct SearchUIIndex {private hotTopicList1: Arraystring [四种醉驾可从宽处理,冰面摔倒至腹腔出血,董宇辉复播,朱一龙拍戏受伤送医,音乐节求婚观众退票,周杰伦新歌歌名,用好“改革开放”这关键一招,男子冬钓失联 遗体在冰缝中被发现,女孩用科目三跳绳 获省级比赛第1名,美丽乡村 幸福生活,]private hotTopicList2: Arraystring [醉驾轻微可不起诉,狄龙被驱逐,劳荣枝希望还清花呗,周海媚告别仪式完成,董宇辉兼任副总裁,小米智能锁自动开门,李家超:基本法第23条明年内实施,山东两幼师出租房内遇害,南京同曦老总大闹裁判休息室,女子出车祸鲨鱼夹插入后脑勺,官方辟谣南京过江隧道连环追尾,上海地铁开启疯狂动物城模式,]private hotTopicList3: Arraystring [朱丹好友起诉朱丹,中年大叔自拍刷屏,西方臻选回应被封号,草莓价格大跳水,库里三分球8中0,国足开启亚洲杯备战,]private currentHistoryHeight: number 0State toastBottom: number 0;State currentInputBoxContent: string private controller new TextInputController()private hotWords: ArrayHotWordsModel []State historyWords: ArrayHistoryWordModel []State inputBoxFocus: boolean false;State hotwordLines: number 0State searchButtonText: string 取消private swiperController: SwiperController new SwiperController()private data: MyDataSource new MyDataSource([])private currentLineNumbs: number 0private context getContext(this) as common.UIAbilityContext;State screenDirection: number this.context.config.directionState showThinkWord: boolean falseState thinkWords: ArrayThinkWordModel []// 当设备横屏时条件成立listener mediaquery.matchMediaSync((orientation: landscape));dialogController: CustomDialogController new CustomDialogController({builder: CustomDialogExample({historyWords: $historyWords,title: 确认全部删除,cancel: this.onCancel,confirm: this.onAccept,}),alignment: DialogAlignment.Default, // 可设置dialog的对齐方式设定显示在底部或中间等默认为底部显示})onCancel() {}onAccept() {console.log(当前数组长度 this.historyWords.length)}configureParamsByScreenDirection() {if (this.screenDirection 0) {this.toastBottom (AppStorage.Get(CommonConstants.ScreenHeight) as number) / 2} else {this.toastBottom (AppStorage.Get(CommonConstants.ScreenWidth) as number) / 2}}DATASOURCE: string[] [联想词测试,测试联想词,全城寻找测试在哪里,找不到人,哈尔滨的啤酒好喝,HarmonyOS版权归属华为]simulatorThinkWord() {this.thinkWords []this.DATASOURCE.forEach((value: string, index: number) {let s: string let m: string let e: string let hIndex: number -1let position value.indexOf(this.currentInputBoxContent)if (position ! -1) {if (position 0) {s value.substr(0, this.currentInputBoxContent.length)} else {s value.substr(0, position)}if (s.length value.length) {position value.substr(s.length).indexOf(this.currentInputBoxContent)if (position -1) {m value.substr(s.length)} else {m value.substr(s.length, this.currentInputBoxContent.length)}if (s.length m.length value.length) {e value.substr(s.length m.length)}}if (s this.currentInputBoxContent) {hIndex 0} else if (m this.currentInputBoxContent) {hIndex 1} else if (e this.currentInputBoxContent) {hIndex 2}this.thinkWords.push(new ThinkWordModel(#000000, #ff0000, hIndex, s, m, e))}})}onPortrait(mediaQueryResult) {if (mediaQueryResult.matches) {//横屏this.screenDirection 1} else {//竖屏this.screenDirection 0}setTimeout(() {this.configureParamsByScreenDirection()}, 300)}aboutToAppear() {this.searchButtonText 取消let list []for (var i 1; i 3; i) {list.push(i.toString());}this.data new MyDataSource(list)this.hotWords.push(new HotWordsModel(HarmonyOS, #E84026, https://developer.harmonyos.com/))this.hotWords.push(new HotWordsModel(实名认证, #5d5d5d))this.hotWords.push(new HotWordsModel(HMS Core, #5d5d5d))this.hotWords.push(new HotWordsModel(Serverless, #5d5d5d))this.hotWords.push(new HotWordsModel(生态市场, #5d5d5d))this.hotWords.push(new HotWordsModel(应用上架, #5d5d5d))this.hotWords.push(new HotWordsModel(仓颉, #5d5d5d))this.hotWords.push(new HotWordsModel(HUAWEI HiAI, #5d5d5d))this.hotWords.push(new HotWordsModel(表盘, #5d5d5d))this.hotWords.push(new HotWordsModel(推送, #5d5d5d))this.hotWords.push(new HotWordsModel(主题, #5d5d5d))this.hotWords.push(new HotWordsModel(公测, #5d5d5d))let portraitFunc this.onPortrait.bind(this)this.listener.on(change, portraitFunc)this.toastBottom (AppStorage.Get(CommonConstants.ScreenHeight) as number) / 2dataPreferences.getPreferences(getContext(this), HistoryWord, (err, preferences) {if (err) {console.error(Failed to get preferences. Code:${err.code},message:${err.message});return;}console.info(Succeeded in getting preferences.);// 进行相关数据操作})}historyWordIndex: number 1submitData(wordModel: HistoryWordModel) {if (wordModel.word.length ! 0) {let exist: boolean falselet existIndex: number -1this.historyWords.forEach((item, index) {if(item.word wordModel.word){if(index ! 0){this.historyWords.splice(index, 1)}exist trueexistIndex index}});if(existIndex 0){console.log(不需要刷新页面)this.currentInputBoxContent this.searchButtonText 取消this.showThinkWord falsereturn}if(!exist){wordModel.index this.historyWordIndexthis.historyWords.push(wordModel)} else {this.historyWordIndexthis.historyWords.push(new HistoryWordModel(this.historyWordIndex, wordModel.word, wordModel.link))}let Test: ArrayHistoryWordModel []this.historyWords.forEach((item, index) {Test.push(item)})Test.sort((a:HistoryWordModel, b:HistoryWordModel) {return b.index - a.index})this.historyWords.length 0Test.forEach((item, index) {this.historyWords.push(item)})this.currentInputBoxContent this.searchButtonText 取消this.showThinkWord false} else {Prompt.showToast({message: 请输入关键词,bottom: px2vp(this.toastBottom)})}}build() {Column() {//一. 输入框 搜索按钮Row() {Stack() {TextInput({ placeholder: 热词搜索, controller: this.controller, text: this.currentInputBoxContent }).height(40vp).fontSize(20fp).enterKeyType(EnterKeyType.Search).placeholderColor(Color.Grey).placeholderFont({ size: 14vp, weight: 400 }).width(100%).padding({ left: 35vp, right: 35vp }).borderStyle(BorderStyle.Solid).borderWidth(1vp).borderColor(Color.Red).onChange((currentContent) {this.currentInputBoxContent currentContentif (this.currentInputBoxContent.length ! 0) {this.searchButtonText 搜索this.showThinkWord truethis.simulatorThinkWord()} else {this.searchButtonText 取消this.showThinkWord false}}).onSubmit((enterKey: EnterKeyType) {this.submitData(new HistoryWordModel(0, this.currentInputBoxContent));})Row() {Image($r(app.media.ic_public_input_search)).width(20vp).height(20vp)if (this.currentInputBoxContent.length ! 0) {Image($r(app.media.ic_public_cancel_filled)).width(20vp).height(20vp).onClick(() {this.currentInputBoxContent })}}.width(100%).hitTestBehavior(HitTestMode.None).justifyContent(FlexAlign.SpaceBetween).padding({ left: 10vp, right: 10vp })}.alignContent(Alignment.Start).width(83%)Text(this.searchButtonText).fontSize(15fp).borderRadius(10vp).padding(5vp).backgroundColor(Color.Red).fontColor(Color.White).width(15%).textAlign(TextAlign.Center).onClick(() {if (搜索 this.searchButtonText) {this.submitData(new HistoryWordModel(0, this.currentInputBoxContent));} else {if (1 router.getLength()) {this.context.terminateSelf()} else {router.back()}}}).stateStyles({focused: {.backgroundColor(Color.Orange)},pressed: {.backgroundColor(Color.Orange)},normal: {.backgroundColor(Color.Red)}})}.justifyContent(FlexAlign.SpaceBetween).padding({ left: 10vp, right: 10vp }).width(100%)Scroll() {Stack() {if (this.showThinkWord) {Column() {ForEach(this.thinkWords, (item: ThinkWordModel, index) {Text() {if (item.wordStart item.wordStart.length ! 0) {Span(item.wordStart).fontSize(18).fontColor(item.highLightIndex 0 ? item.highLightColor : item.normalColor)}if (item.wordMid item.wordMid.length ! 0) {Span(item.wordMid).fontSize(18).fontColor(item.highLightIndex 1 ? item.highLightColor : item.normalColor)}if (item.wordEnd item.wordEnd.length ! 0) {Span(item.wordEnd).fontSize(18).fontColor(item.highLightIndex 2 ? item.highLightColor : item.normalColor)}}.width(100%).height(50).textAlign(TextAlign.Center).fontSize(18).textAlign(TextAlign.Start).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })Divider().width(100%).height(1).color(Color.Grey)})}.width(100%).height(100%).padding({ left: 12vp, right: 12vp }).backgroundColor(Color.White)} else {Column() {//二. 搜索历史if (this.historyWords.length ! 0) {Row() {Text(历史搜索).fontSize(20fp).fontWeight(FontWeight.Bold)Image($r(app.media.ic_public_delete)).width(20vp).height(20vp).onClick(() {this.dialogController.open()})}.width(100%).margin({ top: 20vp }).padding({ left: 10vp, right: 10vp }).justifyContent(FlexAlign.SpaceBetween)Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {ForEach(this.historyWords, (item: HistoryWordModel, index) {Text(item.word).fontSize(15).margin(5).fontColor(#5d5d5d).maxLines(1).backgroundColor(#f6f6f6).padding({ left: 20, right: 20, top: 5, bottom: 5 }).borderRadius(30vp).textOverflow({ overflow: TextOverflow.Ellipsis }).onClick((){this.submitData(item);})})}.width(100%).margin({ top: 12vp }).onAreaChange((oldValue: Area, newValue: Area) {let newHeight newValue.height as numberif(this.currentHistoryHeight 0){this.currentHistoryHeight newHeight}this.currentLineNumbs newHeight / this.currentHistoryHeightconsole.log(当前行数: this.currentLineNumbs)if (this.currentLineNumbs MAX_LINES) {this.historyWords this.historyWords.slice(0, this.historyWords.length-1)}})}//三. 热门搜索Text(热门搜索).fontSize(20fp).width(100%).fontWeight(FontWeight.Bold).margin({ left: 10vp, top: 20vp })Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {ForEach(this.hotWords, (item: HotWordsModel, index) {Text(item.word).fontSize(15).margin(5).fontColor(item.wordColor).backgroundColor(#f6f6f6).padding({ left: 20, right: 20, top: 5, bottom: 5 }).borderRadius(30vp).onClick(() {if (this.hotWords[index].wordLink this.hotWords[index].wordLink.length ! 0) {router.pushUrl({ url: custompages/WebView, params: {targetUrl: this.hotWords[index].wordLink,} }).then(() {console.info(Succeeded in jumping to the second page.)}).catch((error) {console.log(error)})} else if(this.hotWords[index].word){this.submitData(new HistoryWordModel(0, this.hotWords[index].word));}})})}.width(100%).margin({ top: 12vp }).onAreaChange((oldValue: Area, newValue: Area) {console.log(热词高度 newValue.height )})//四. 热门帖子Text(热门帖子).fontSize(20fp).width(100%).fontWeight(FontWeight.Bold).margin({ left: 10vp, top: 20vp })Swiper(this.swiperController) {LazyForEach(this.data, (item: string, index: number) {if (index 0) {this.swiperList(this.hotTopicList1)} else if (index 1) {this.swiperList(this.hotTopicList2)} else if (index 2) {this.swiperList(this.hotTopicList3)}}, item item)}.padding({ bottom: 50vp }).displayMode(SwiperDisplayMode.AutoLinear).margin({ top: 12vp }).cachedCount(2).index(1).indicator(false).loop(true).itemSpace(0).curve(Curve.Linear)}}}}.scrollBar(BarState.Off)}.padding({ top: px2vp(AppStorage.Get(CommonConstants.StatusBarHeight)) })}Builder swiperList(data: string[]){Column() {ForEach(data, (da, i) {if(i 0){Text(){Span((i1). ).fontColor(#E84026).fontSize(20)Span(da).fontColor(#5d5d5d).fontSize(18)}.width(100%).height(50)} else if(i 1){Text(){Span((i1). ).fontColor(#ED6F21).fontSize(20)Span(da).fontColor(#5d5d5d).fontSize(18)}.width(100%).height(50)} else if(i 2){Text(){Span((i1). ).fontColor(#F9A01E).fontSize(20)Span(da).fontColor(#5d5d5d).fontSize(18)}.width(100%).height(50)} else {Text((i 1) . da).fontColor(#5d5d5d).width(100%).height(50).textAlign(TextAlign.Center).fontSize(18).textAlign(TextAlign.Start)}if (i ! this.hotTopicList1.length - 1) {Divider().width(100%).vertical(false)}})}.borderRadius(10vp).margin({ left: 10vp, right: 10vp, bottom: 25vp }).backgroundColor(#f6f6f6).padding(10vp)} }CustomDialog struct CustomDialogExample {controller: CustomDialogControllertitle: string Link historyWords: Arraystringcancel: () voidconfirm: () voidbuild() {Column() {Text(this.title).fontSize(20).margin({ top: 10, bottom: 10 })Flex({ justifyContent: FlexAlign.SpaceAround }) {Button(取消).onClick(() {this.controller.close()this.cancel()}).backgroundColor(0xffffff).fontColor(Color.Black)Button(确认).onClick(() {this.controller.close()this.confirm()this.historyWords []}).backgroundColor(0xffffff).fontColor(Color.Red)}.margin({ bottom: 10 })}} }class MyDataSource implements IDataSource {private list: number[] []private listener: DataChangeListenerconstructor(list: number[]) {this.list list}totalCount(): number {return this.list.length}getData(index: number): any {return this.list[index]}registerDataChangeListener(listener: DataChangeListener): void {this.listener listener}unregisterDataChangeListener() {} } 历史词数据结构 HistoryWordModel.ets export default class HistoryWordModel {public index: numberpublic link: stringpublic word: stringconstructor(index, word, link?) {this.index indexthis.link linkthis.word word} } 热词数据结构 HotWordModel.ets export default class HotWordModel {public word: string //词语public wordColor: string //文字颜色public wordLink?: string //文字超链接constructor(word, wordColor, wordLink?) {this.word wordthis.wordColor wordColorthis.wordLink wordLink} } 联想词数据结构 ThinkWordModel.ets export default class ThinkWordModel {public normalColor: stringpublic highLightColor: stringpublic wordStart: string //词语public wordMid: string //文字颜色public wordEnd: string //文字超链接public highLightIndex: numberconstructor(normalColor: string, highLightColor: string, highLightIndex: number,wordStart?: string, wordMid?: string,wordEnd?: string) {this.normalColor normalColorthis.highLightColor highLightColorthis.highLightIndex highLightIndexthis.wordStart wordStartthis.wordMid wordMidthis.wordEnd wordEnd}} 总结 对于AndroidiOS开发者来讲在HarmonyOS中实现动态布局还是非常容易陷入之前的开发思路中新的平台熟悉API很重要 鸿蒙最值得程序员入行 为什么这么说市场是决定人力需求的数据说话最管用 1、鸿蒙其全栈自研头部大厂商都陆续加入合作开发鸿蒙原生应用——人才需求上涨。 2、鸿蒙作为新系统、新技术而现在市面上技术人才少——高薪招聘开启。 3、鸿蒙18N生态不仅只有应用开发还有车载、数码、智能家居、家电等——就业范围广。 4、纯血鸿蒙目前没有多少人熟悉。都处于0基础同一起跑线——无行业内卷。 开发者最需要什么岗位多、薪资高、不内卷、行业竞争低。而当下的鸿蒙恰恰符合要求。 那么这么好的鸿蒙岗位应聘要求都很高吧其实不然鸿蒙作为新出的独立系统其源头上大家都处于同一水平线上一开始的技术要求都不会很高毕竟面试官也是刚起步学习。招聘要求示例 从信息看出几乎应职要求是对标有开发经验的人群。可以说鸿蒙对开发者非常友好尽管上面没提鸿蒙要求但是面试都会筛选具有鸿蒙开发技能的人。我们程序员都知道学习开发技术最先是从语言学起鸿蒙语言有TS、ArkTS等语法那么除了这些基础知识之外其核心技术点有那些呢下面就用一张整理出的鸿蒙学习路线图表示 从上面的OpenHarmony技术梳理来看鸿蒙的学习内容也是很多的。现在全网的鸿蒙学习文档也是非常的少下面推荐一些完整内容可在头像页保存或这qr23.cn/AKFP8k甲助力 内容包含《鸿蒙NEXT星河版开发学习文档》 ArkTS声明式ArkUI多媒体通信问题系统移植系统裁剪FW层的原理各种开发调试工具智能设备开发分布式开发等等。 这些就是对往后开发者的分享希望大家多多点赞关注喔
http://www.zqtcl.cn/news/324502/

相关文章:

  • 网站建设适应全屏如何自动深圳市哪里最繁华
  • 杭州网站推广公司阿里云wordpress 安装目录
  • 厦门优秀网站建设app项目开发流程
  • 工作设计室网站海外网站代理
  • 室内设计官方网站没网站怎么做cpa
  • 哪个网站做欧洲旅游攻略好wordpress编辑器字体大小
  • aspcms 手机网站wordpress 刷浏览量
  • dw网站首页的导航怎么做网站建设企业建站模板
  • 平台型网站建设网站关键词优化seo
  • 齿轮机械东莞网站建设技术支持热搜词排行榜关键词
  • 河南专业做网站网站推广优化c重庆
  • 温州网站建设钱建设工程公司网站
  • 做笑话网站全国大学生职业生涯规划大赛官网
  • 便宜购 网站建设平台推广引流怎么做
  • 怎么用记事本做钓鱼网站制作公司网页的步骤
  • 机械设备东莞网站建设智慧软文网站
  • 个人网站需不需要搭建服务器蘑菇短视频2023版特色功能
  • 网站建设公司是什么东兰县建设局网站
  • 网站优化排名方案软件发布网
  • 企业网站开发价钱低企业策划案例
  • 网站建设帐号网站导入页欣赏
  • ftp 迁移 网站建筑公司商标logo设计
  • 没钱怎么做网站wordpress 链接修改插件
  • 建一个网站需要多久建设银行官网登录入口
  • 贸易公司网站制作邢台哪里做网站
  • 2018网站开发的革新帮别人起名 做ppt的网站
  • 有哪些做问卷调查赚钱的网站6长沙网站建设技术
  • 烟台做网站需要多少钱制作ppt的软件是什么
  • 泉州模板开发建站wordpress显示一个类目
  • 河南造价信息网官网为什么要做网站优化