个人网站可以挂广告吗,wordpress手机软件,个人app开发平台免费,wordpress私密评论前言
项目需求是展示标签#xff0c;标签的个数不定#xff0c;一行展示不行就自行换行。但是#xff0c;使用鸿蒙原生的 Grid 后发现特别的难看。然后就想着自定义控件。找了官方文档#xff0c;发现2个重要的实现方法#xff0c;但是#xff0c;官方的demo中讲的很少标签的个数不定一行展示不行就自行换行。但是使用鸿蒙原生的 Grid 后发现特别的难看。然后就想着自定义控件。找了官方文档发现2个重要的实现方法但是官方的demo中讲的很少需要自己去看去思考。
效果图如下 注意点
需要计算整体布局的宽高这和 Android 差不多。注意 margin 的计算
具体的代码如下
/*** 自定义标签页面*/
Component struct CustomTagView {screenWidth: number 0aboutToAppear(): void {let dis display.getDefaultDisplaySync();let width dis.widthlet height dis.height// width 是单位是 px, 转换为 vp ,因为 onMeasureSize 和 onPlaceChildren 得到的 width margin 以及 padding 都是 vplet w px2vp(width)let h px2vp(height)this.screenWidth wconsole.log(TagView aboutToAppear width width , height height , w w , h h)}Builder childBuilder() {}BuilderParam buildTagView: () void this.childBuilderresult: SizeResult {width: 0,height: 0}// 第一步计算各子组件的实际大小以及设置布局本身的大小onMeasureSize(selfLayoutInfo: GeometryInfo, children: ArrayMeasurable, constraint: ConstraintSizeOptions) {let parentWidth selfLayoutInfo.widthlet parentHeight selfLayoutInfo.heightconsole.log(TagView onMeasureSize parentWidth parentWidth , parentHeight parentHeight)let startPosX 0let columNumber 1let childHeight 0children.forEach((child) {// 得到子控件的实际大小let result: MeasureResult child.measure({minHeight: constraint.minHeight,minWidth: constraint.minWidth,maxWidth: constraint.maxWidth,maxHeight: constraint.maxHeight})let padding child.getPadding()let border child.getBorderWidth()console.log(TagView onMeasureSize child width result.width , height result.height , padding [ padding.start , padding.end , padding.top , padding.bottom ], border [ border.start , border.end , border.top , border.bottom ])/// 计算 布局所需的高度 宽度默认为屏幕的宽度childHeight result.height child.getMargin().topstartPosX result.width child.getMargin().startif (startPosX parentWidth) {columNumberstartPosX result.width child.getMargin().start}})// 父布局的宽和高即承载 child 布局的宽和高这里指的就是 TagView 的宽和高this.result.width this.screenWidth;this.result.height childHeight * columNumber 10 // 加10是为了底部多点空间return this.result;}// 第二步放置各子组件的位置onPlaceChildren(selfLayoutInfo: GeometryInfo, children: ArrayLayoutable, constraint: ConstraintSizeOptions) {let startPosX 0let startPosY 0let posY 0let parentWidth selfLayoutInfo.widthconsole.log(TagView onPlaceChildren parentWidth selfLayoutInfo.width , parentHeight selfLayoutInfo.height)children.forEach((child) {startPosX child.getMargin().start// 如果一行的控件的长度大于屏幕宽度则换行if (startPosX child.measureResult.width parentWidth) {startPosY child.measureResult.height child.getMargin().topstartPosX child.getMargin().start}posY startPosYconsole.log(TagView child width child.measureResult.width , height child.measureResult.height , margin left child.getMargin().start)child.layout({ x: startPosX, y: posY })startPosX child.measureResult.width})}build() {this.buildTagView()}
}调用的方法也很简单下面是个调用的demo
Entry
Component
struct TestPage {State name: string hello// Provide 参数 key 必须是 stringProvide(provideName) pName: string 哈哈Provide(count) count: number 4textWidth: number 0aboutToAppear(): void {let width MeasureText.measureText({ textContent: 返厂无忧券1, fontSize: 13vp });let w px2vp(width)console.log(TestPage aboutToAppear width width , w w)// 如果有换行那么长度等于最长的一行let textSize MeasureText.measureTextSize({ textContent: 返厂无忧券1\n返厂无忧券1234, fontSize: 13vp })let w2 textSize.widthlet h2 textSize.heightthis.textWidth px2vp(w2 as number)console.log(TestPage aboutToAppear w2 w2 , h2 h2)}// Build 参数按值传递状态变量改变不会引起 Build 方法内的 UI 刷新// 但是Text( ----- this.name) 中的 UI 会刷新BuildernameView(name: string) {Text(name)}// Build 参数按引用传递的话状态变量(State name) 改变Build 方法内的 UI 会刷新BuildernameView2(tmp: Tmp) {Text(V2 : name tmp.params)}// 通过builder的方式传递多个组件作为自定义组件的一级子组件即不包含容器组件如ColumnBuilderTagViewChildren() {ForEach([你好哪吒2, 大圣归来啊, 我是名字超长的但是很厉害, hello world, 你真的好厉害啊哈哈, 没空看, 非凡,再来一个很长的名字啊, OK],(data: string, index: number) { // 暂不支持lazyForEach的写法Text(data).fontSize(13).fontColor(Color.Red).margin({ left: 3, top: 4 })// .width(100)// .height(100).borderWidth(1).border({ radius: 4 }).padding(5).textAlign(TextAlign.Center)// .offset({ x: 10, y: 20 })})}build() {Column() {Column() {CustomTagView({ buildTagView: this.TagViewChildren })}.backgroundColor(Color.Pink).margin({ top: 2 })}.width(100%).height(100%).alignItems(HorizontalAlign.Start)}
}
好了具体的可以参考下 demo 啦有疑问的可以一起交流。