HarmonyOS 鸿蒙Next:自定义左中右布局,空间够时中间组件尽量居中

发布于 1周前 作者 nodeper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next:自定义左中右布局,空间够时中间组件尽量居中

效果图:

代码:

@Component export struct NavigationBarLayout{

@Builder doNothingBuilder() { };

@BuilderParam buildLeft:()=>void = this.doNothingBuilder

@BuilderParam buildCenter:()=>void = this.doNothingBuilder

@BuilderParam buildRight:()=>void = this.doNothingBuilder

onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) { // let startPos = 150;

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> left:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> center:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> right:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>


<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  left = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  center = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  right = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> leftBound = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> rightBound = selfLayoutInfo.width
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (left){
  left.layout({ x: <span class="hljs-number"><span class="hljs-number">0</span></span>, y: (selfLayoutInfo.height-left.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  leftBound = left.measureResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (right){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> x = selfLayoutInfo.width - right.measureResult.width
  right.layout({
    x: x,
    y: (selfLayoutInfo.height-right.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  rightBound = x
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (center){

  <span class="hljs-comment"><span class="hljs-comment">// 绝对中心</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> centerBound = <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.max(leftBound, selfLayoutInfo.width - rightBound)
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> centerWidth = selfLayoutInfo.width - centerBound * <span class="hljs-number"><span class="hljs-number">2</span></span>

  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (centerWidth&gt;center.measureResult.width){
    <span class="hljs-comment"><span class="hljs-comment">// 空间够,居中</span></span>
    center.layout({
      x: (selfLayoutInfo.width - center.measureResult.width)/<span class="hljs-number"><span class="hljs-number">2</span></span>,
      y: (selfLayoutInfo.height-center.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  }
  <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
    <span class="hljs-comment"><span class="hljs-comment">// 空间不够</span></span>
    center.layout({
      x: leftBound + (rightBound - leftBound - center.measureResult.width)/<span class="hljs-number"><span class="hljs-number">2</span></span>,
      y: (selfLayoutInfo.height-center.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  }

}

}

onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) : SizeResult { let result: SizeResult = { width: 0, height: 0 };

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> left:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> center:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> right:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>


<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  left = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  center = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  right = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> width = selfLayoutInfo.width

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (left){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = left.measure({
    maxWidth: <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.min(width, selfLayoutInfo.width/<span class="hljs-number"><span class="hljs-number">2</span></span>),
    maxHeight: selfLayoutInfo.height })

  result.height = <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.max(result.height, childResult.height)
  width -= childResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (right){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = right.measure({
    maxWidth: <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.min(width, selfLayoutInfo.width/<span class="hljs-number"><span class="hljs-number">2</span></span>),
    maxHeight: selfLayoutInfo.height })

  result.height = <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.max(result.height, childResult.height)
  width -= childResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (center){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = center.measure({
    maxWidth: width,
    maxHeight: selfLayoutInfo.height })

  result.height = <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.max(result.height, childResult.height)
}


result.width = selfLayoutInfo.width;
<span class="hljs-comment"><span class="hljs-comment">// result.height = 400;</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> result;

}

@Builder builder(){ this.buildLeft() this.buildCenter() this.buildRight() }

build() { this.builder() }

}

@Preview @Component struct NavigationBarLayoutPreview{

@Builder buildLeft(){ Text(‘left’) .backgroundColor(Color.Red) }

@Builder buildLongLeft(){ Text(‘leftleftleftleft’) .backgroundColor(Color.Red) }

@Builder buildCenter(){ Text(‘center’) .backgroundColor(Color.Yellow) }

@Builder buildLongCenter(){ Text(‘centercentercenter’) .backgroundColor(Color.Yellow) }

@Builder buildRight(){ Text(‘Right’) .backgroundColor(Color.Blue) }

@Builder buildLongRight(){ Text(‘RightRightRightRight’) .backgroundColor(Color.Blue) }

build() { Column({space:8}){ NavigationBarLayout({ buildLeft:this.buildLeft, buildCenter:this.buildCenter, buildRight:this.buildRight, })

  NavigationBarLayout({
    buildLeft:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongLeft,
    buildCenter:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter,
    buildRight:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight,
  })

  NavigationBarLayout({
    buildLeft:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft,
    buildCenter:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter,
    buildRight:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight,
  })

  NavigationBarLayout({
    buildLeft:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft,
    buildCenter:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongCenter,
    buildRight:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongRight,
  })

  NavigationBarLayout({
    buildLeft:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongLeft,
    buildCenter:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongCenter,
    buildRight:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongRight,
  })

  NavigationBarLayout({
    buildCenter:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter,
    buildRight:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight,
  })


  NavigationBarLayout({
    buildLeft:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft,
    buildRight:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight,
  })

  NavigationBarLayout({
    buildLeft:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft,
    buildCenter:<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter,
  })
}

.width(200) }

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

5 回复
NavigationBarLayout({
  buildLeft:()=>{this.buildLeft()},
  buildCenter:()=>{this.buildCenter()},
  buildRight:()=>{this.buildRight()},
})<button id="copyCode" style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; width: 62px; right: 7px; font-size: 14px; display: none;">复制</button>

使用时用要

()=>{this.buildLeft()}    // buildLeft方法里面使用了this的话,this对象不是NavigationBarLayout

而不是

buildLeft:this.buildLeft  // buildLeft方法里面使用了this的话,this对象是NavigationBarLayout

更新:


@Component export struct NavigationBarLayout{

@Builder doNothingBuilder() { };

@BuilderParam buildLeft:()=>void = this.doNothingBuilder

@BuilderParam buildCenter:()=>void = this.doNothingBuilder

@BuilderParam buildRight:()=>void = this.doNothingBuilder

onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) { // let startPos = 150;

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> left:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> center:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> right:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>


<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  left = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  center = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  right = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> leftBound = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> rightBound = selfLayoutInfo.width
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (left){
  left.layout({ x: <span class="hljs-number"><span class="hljs-number">0</span></span>, y: (selfLayoutInfo.height-left.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  leftBound = left.measureResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (right){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> x = selfLayoutInfo.width - right.measureResult.width
  right.layout({
    x: x,
    y: (selfLayoutInfo.height-right.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  rightBound = x
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (center){

  <span class="hljs-comment"><span class="hljs-comment">// 绝对中心</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> centerBound = <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.max(leftBound, selfLayoutInfo.width - rightBound)
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> centerWidth = selfLayoutInfo.width - centerBound * <span class="hljs-number"><span class="hljs-number">2</span></span>

  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (centerWidth&gt;center.measureResult.width){
    <span class="hljs-comment"><span class="hljs-comment">// 空间够,居中</span></span>
    center.layout({
      x: (selfLayoutInfo.width - center.measureResult.width)/<span class="hljs-number"><span class="hljs-number">2</span></span>,
      y: (selfLayoutInfo.height-center.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  }
  <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
    <span class="hljs-comment"><span class="hljs-comment">// 空间不够</span></span>
    center.layout({
      x: leftBound + (rightBound - leftBound - center.measureResult.width)/<span class="hljs-number"><span class="hljs-number">2</span></span>,
      y: (selfLayoutInfo.height-center.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  }

}

}

onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) : SizeResult { let result: SizeResult = { width: 0, height: 0 };

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> left:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> center:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> right:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>


<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  left = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  center = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  right = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> width = selfLayoutInfo.width

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (left){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = left.measure({
    maxWidth: <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.min(width, selfLayoutInfo.width/<span class="hljs-number"><span class="hljs-number">2</span></span>),
    maxHeight: selfLayoutInfo.height })

  <span class="hljs-comment"><span class="hljs-comment">// result.height = Math.max(result.height, childResult.height)</span></span>
  width -= childResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (right){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = right.measure({
    maxWidth: <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.min(width, selfLayoutInfo.width/<span class="hljs-number"><span class="hljs-number">2</span></span>),
    maxHeight: selfLayoutInfo.height })

  <span class="hljs-comment"><span class="hljs-comment">// result.height = Math.max(result.height, childResult.height)</span></span>
  width -= childResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (center){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = center.measure({
    maxWidth: width,
    maxHeight: selfLayoutInfo.height })

  <span class="hljs-comment"><span class="hljs-comment">// result.height = Math.max(result.height, childResult.height)</span></span>
}


result.width = selfLayoutInfo.width;
result.height = selfLayoutInfo.height;
<span class="hljs-comment"><span class="hljs-comment">// result.height = 400;</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> result;

}

@Builder builder(){ this.buildLeft() this.buildCenter() this.buildRight() }

build() { this.builder() }

}

@Preview @Component struct NavigationBarLayoutPreview{

@Builder buildLeft(){ Text(‘left’) .backgroundColor(Color.Red) }

@Builder buildLongLeft(){ Text(‘leftleftleftleft’) .backgroundColor(Color.Red) }

@Builder buildCenter(){ Text(‘center’) .backgroundColor(Color.Yellow) }

@Builder buildLongCenter(){ Text(‘centercentercenter’) .backgroundColor(Color.Yellow) }

@Builder buildRight(){ Text(‘Right’) .backgroundColor(Color.Blue) }

@Builder buildLongRight(){ Text(‘RightRightRightRight’) .backgroundColor(Color.Blue) }

build() { Column({space:8}){ NavigationBarLayout({ buildLeft:()=>{this.buildLeft()}, buildCenter:()=>{this.buildCenter()}, buildRight:()=>{this.buildRight()}, }) .height(50)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)


  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
}
.width(<span class="hljs-number"><span class="hljs-number">200</span></span>)

}

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

更新:


@Component export struct NavigationBarLayout{

@Builder doNothingBuilder() { };

@BuilderParam buildLeft:()=>void = this.doNothingBuilder

@BuilderParam buildCenter:()=>void = this.doNothingBuilder

@BuilderParam buildRight:()=>void = this.doNothingBuilder

onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) { // let startPos = 150;

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> left:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> center:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> right:Layoutable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>


<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  left = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  center = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  right = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> leftBound = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> rightBound = selfLayoutInfo.width
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (left){
  left.layout({ x: <span class="hljs-number"><span class="hljs-number">0</span></span>, y: (selfLayoutInfo.height-left.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  leftBound = left.measureResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (right){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> x = selfLayoutInfo.width - right.measureResult.width
  right.layout({
    x: x,
    y: (selfLayoutInfo.height-right.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  rightBound = x
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (center){

  <span class="hljs-comment"><span class="hljs-comment">// 绝对中心</span></span>
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> centerBound = <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.max(leftBound, selfLayoutInfo.width - rightBound)
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> centerWidth = selfLayoutInfo.width - centerBound * <span class="hljs-number"><span class="hljs-number">2</span></span>

  <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (centerWidth&gt;center.measureResult.width){
    <span class="hljs-comment"><span class="hljs-comment">// 空间够,居中</span></span>
    center.layout({
      x: (selfLayoutInfo.width - center.measureResult.width)/<span class="hljs-number"><span class="hljs-number">2</span></span>,
      y: (selfLayoutInfo.height-center.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  }
  <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
    <span class="hljs-comment"><span class="hljs-comment">// 空间不够</span></span>
    center.layout({
      x: leftBound + (rightBound - leftBound - center.measureResult.width)/<span class="hljs-number"><span class="hljs-number">2</span></span>,
      y: (selfLayoutInfo.height-center.measureResult.height)/<span class="hljs-number"><span class="hljs-number">2</span></span> })
  }

}

}

onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) : SizeResult { let result: SizeResult = { width: 0, height: 0 };

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> left:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> center:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> right:Measurable|<span class="hljs-literal"><span class="hljs-literal">undefined</span></span>


<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> index = <span class="hljs-number"><span class="hljs-number">0</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  left = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  center = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight !== <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.doNothingBuilder){
  right = children[index]
  index ++
}

<span class="hljs-keyword"><span class="hljs-keyword">let</span></span> width = selfLayoutInfo.width

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (left){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = left.measure({
    maxWidth: <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.min(width, selfLayoutInfo.width/<span class="hljs-number"><span class="hljs-number">2</span></span>),
    maxHeight: selfLayoutInfo.height })

  <span class="hljs-comment"><span class="hljs-comment">// result.height = Math.max(result.height, childResult.height)</span></span>
  width -= childResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (right){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = right.measure({
    maxWidth: <span class="hljs-built_in"><span class="hljs-built_in">Math</span></span>.min(width, selfLayoutInfo.width/<span class="hljs-number"><span class="hljs-number">2</span></span>),
    maxHeight: selfLayoutInfo.height })

  <span class="hljs-comment"><span class="hljs-comment">// result.height = Math.max(result.height, childResult.height)</span></span>
  width -= childResult.width
}

<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (center){
  <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> childResult: MeasureResult = center.measure({
    maxWidth: width,
    maxHeight: selfLayoutInfo.height })

  <span class="hljs-comment"><span class="hljs-comment">// result.height = Math.max(result.height, childResult.height)</span></span>
}


<span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (<span class="hljs-keyword"><span class="hljs-keyword">typeof</span></span> constraint.maxWidth == <span class="hljs-string"><span class="hljs-string">'number'</span></span>){
  result.width = constraint.maxWidth
}
<span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
  result.width = selfLayoutInfo.width
}

result.height = selfLayoutInfo.height
<span class="hljs-comment"><span class="hljs-comment">// result.height = 400;</span></span>
<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> result;

}

@Builder builder(){ this.buildLeft() this.buildCenter() this.buildRight() }

build() { this.builder() }

}

@Preview @Component struct NavigationBarLayoutPreview{

@Builder buildLeft(){ Text(‘left’) .backgroundColor(Color.Red) }

@Builder buildLongLeft(){ Text(‘leftleftleftleft’) .backgroundColor(Color.Red) }

@Builder buildCenter(){ Text(‘center’) .backgroundColor(Color.Yellow) }

@Builder buildLongCenter(){ Text(‘centercentercenter’) .backgroundColor(Color.Yellow) }

@Builder buildRight(){ Text(‘Right’) .backgroundColor(Color.Blue) }

@Builder buildLongRight(){ Text(‘RightRightRightRight’) .backgroundColor(Color.Blue) }

build() { Column({space:8}){ NavigationBarLayout({ buildLeft:()=>{this.buildLeft()}, buildCenter:()=>{this.buildCenter()}, buildRight:()=>{this.buildRight()}, }) .height(50)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLongRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)


  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildRight:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildRight()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)

  NavigationBarLayout({
    buildLeft:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildLeft()},
    buildCenter:()=&gt;{<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.buildCenter()},
  })
    .height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
}
.width(<span class="hljs-number"><span class="hljs-number">200</span></span>)

}

}<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

在HarmonyOS(鸿蒙)开发中,实现自定义左中右布局并确保空间足够时中间组件尽量居中,可以通过Flexbox布局或Grid布局来实现。Flexbox布局下,可以将容器设置为display: flex; justify-content: space-between;,然后通过在左侧和右侧放置固定宽度的元素,中间元素则设置为flex-grow: 1;以填充剩余空间并自动居中(需结合text-align: center或内部子元素的居中设置)。如果空间不足,中间元素可能会压缩。如果问题依旧没法解决请加我微信,我的微信是itying888。

回到顶部