HarmonyOS 鸿蒙Next:自定义左中右布局,空间够时中间组件尽量居中
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>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>
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>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:()=>{<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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.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>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:()=>{<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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.height(<span class="hljs-number"><span class="hljs-number">50</span></span>)
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()},
})
.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。