用户3116712
用户3116712
  • 发布:2026-08-30 09:23
  • 更新:2026-08-30 09:23
  • 阅读:8

如何实现一个自定义高度的底部弹窗

分类:HBuilder

问题现象
需要实现的底部弹窗可以设置一个最大高度。同时,实现的底部弹窗需要从下往上出现。

如果弹窗内部视图的高度超过了这个最大高度,弹窗内部的视图就以这个自定义最大高度进行滚动展示;
如果弹窗内部视图的高度没有超过这个最大高度,那么弹窗内部视图就完全展示;
背景知识
组件的constraintSize属性用于设置约束尺寸,组件布局时,进行尺寸范围限制。

对于组件的显示方式,转场主要通过transition属性配置转场参数,在组件插入和删除时显示过渡动效,主要用于容器组件中的子组件插入和删除时,提升用户体验。

解决方案
首先,通过使用容器组件的constraintSize属性对视图进行高度限制,constraintSize的优先级高于Width和Height,constraintSize里面的maxHeight小于Height时,就会滚动展示。接着,实现弹窗从底部向上显示,通过设置组件transition属性的转场参数。

示例代码如下:

@CustomDialog
struct CustomDialogExample {
// 最大可滚动区域高度
maxScrollHeight: number = 70;
// 视图是否显示,用于底部弹窗出现与消失时的动效处理
@Link showFlag: Visibility;
controller: CustomDialogController;
scroller: Scroller = new Scroller;
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];

build() {
Column({ space: 5 }) {
RelativeContainer() {
Text('标题')
.fontSize(17)
.fontColor(Color.Black)
.fontWeight(FontWeight.Bold)
.alignRules({
middle: { anchor: 'container', align: HorizontalAlign.Center },
center: { anchor: 'container', align: VerticalAlign.Center }
});
}
.width('100%')
.height(48);

  Scroll(this.scroller) {  
    Column() {  
      ForEach(this.arr, (item: number) => {  
        Text(item.toString())  
          .width('90%')  
          .height(50)  
          .backgroundColor(0xFFFFFF)  
          .borderColor(Color.Black)  
          .fontSize(16)  
          .textAlign(TextAlign.Center);  
        Divider()  
          .vertical(false)  
          .strokeWidth(0.5)  
          .width('60%');  
      }, (item: string) => item);  
    }.width('100%');  
  }  
  .edgeEffect(EdgeEffect.Spring)  
  .scrollSnap({  
    snapAlign: ScrollSnapAlign.START,  
    snapPagination: 400,  
    enableSnapToStart: true,  
    enableSnapToEnd: true  
  })  
  // 使用constraintSize方法可以设置约束尺寸,组件布局时,进行尺寸范围限制  
  .constraintSize({ maxHeight: this.maxScrollHeight + '%' });  

}  
.justifyContent(FlexAlign.Center)  
.backgroundColor('#f5f5f5')  
.borderRadius({  
  topLeft: '16',  
  topRight: '16'  
})  
.visibility(this.showFlag)  
.transition(TransitionEffect.OPACITY.animation({ duration: 200 })  // 弹窗出现与消失的动效  
  .combine(TransitionEffect.translate({ y: 100 })),  
  (transitionIn: boolean) => {  
    if (!transitionIn) {  
      this.controller.close();  
    }  
  }  
);  

}
}

@Entry
@Component
struct CustomDialogDemo {
// 最大可滚动区域高度
@State maxScrollHeight: number = 70;
@State settingDialogShowFlag: Visibility = Visibility.Visible;
dialogController: CustomDialogController = new CustomDialogController({
builder: CustomDialogExample({
maxScrollHeight: this.maxScrollHeight,
showFlag: this.settingDialogShowFlag
}),
alignment: DialogAlignment.Bottom,
width: '100%',
// customStyle需要设置为true,否则底部弹窗出现的动效会有问题
customStyle: true,
autoCancel: true,
// 修改点击弹窗外部区域和返回操作时弹窗消失的方式,这里的处理会有一个动效。否则弹窗会以默认的方式消失
onWillDismiss: () => {
this.settingDialogShowFlag = Visibility.Hidden;
}
});

build() {
Column() {
Row({ space: 5 }) {
Row() {
Button('减10')
.onClick(() => {
this.maxScrollHeight -= 10;
});
};

    Row() {  
      Text(this.maxScrollHeight + '%')  
        .width('40%')  
        .height(45)  
        .textAlign(TextAlign.Center)  
        .backgroundColor('#f5f5f5');  
    };  

    Row() {  
      Button('加10')  
        .onClick(() => {  
          this.maxScrollHeight += 10;  
        });  
    };  
  };  

  Button('打开底部弹窗')  
    .onClick(() => {  
      this.settingDialogShowFlag = Visibility.Visible;  
      this.dialogController.open();  
    });  
}.justifyContent(FlexAlign.Center).width('100%').height('100%');  

}
}

https://sites.google.com/view/8ojcyz21/home
https://sites.google.com/view/8votdo34/home
https://sites.google.com/view/2glnsx28/home
https://sites.google.com/view/5cljni07/home
https://sites.google.com/view/8prkhh07/home
https://sites.google.com/view/7khplo30/home
https://sites.google.com/view/1iwwoj29/home
https://sites.google.com/view/5lokbt20/home
https://sites.google.com/view/8ucjap35/home
https://sites.google.com/view/3vmwqk28/home
https://sites.google.com/view/4hqmfe46/home
https://sites.google.com/view/8jjhsd05/home
https://sites.google.com/view/2ajqbl31/home
https://sites.google.com/view/8eroul90/home
https://sites.google.com/view/8whpgb50/home
https://sites.google.com/view/7fhwgy79/home
https://sites.google.com/view/8otxzd32/home
https://sites.google.com/view/0skklh79/home
https://sites.google.com/view/7epixg32/home
https://sites.google.com/view/2fdymh76/home
https://sites.google.com/view/1qzbbd10/home
https://sites.google.com/view/3betru91/home
https://sites.google.com/view/0fjymy02/home
https://sites.google.com/view/1tuyht61/home
https://sites.google.com/view/3lqsci93/home
https://sites.google.com/view/4moosi57/home
https://sites.google.com/view/0ebmiw84/home
https://sites.google.com/view/4usaol83/home
https://sites.google.com/view/0hknci80/home
https://sites.google.com/view/7ldcgt68/home
https://sites.google.com/view/8emzek60/home
https://sites.google.com/view/9oaldi75/home
https://sites.google.com/view/1hujlx46/home
https://sites.google.com/view/9krrdx96/home
https://sites.google.com/view/0rdwwl74/home
https://sites.google.com/view/4oalem69/home
https://sites.google.com/view/7tpgsy97/home
https://sites.google.com/view/4sjvkh25/home
https://sites.google.com/view/6ixmrs26/home
https://sites.google.com/view/7jjcws23/home
https://sites.google.com/view/4entvi31/home
https://sites.google.com/view/0hqtsy80/home
https://sites.google.com/view/2vthve29/home
https://sites.google.com/view/2wjwhq06/home
https://sites.google.com/view/7lnlrg38/home
https://sites.google.com/view/3jwoff92/home
https://sites.google.com/view/9exfcx28/home
https://sites.google.com/view/6ayynm56/home
https://sites.google.com/view/2mkert04/home
https://sites.google.com/view/9bfpha34/home
https://sites.google.com/view/7kwinp20/home
https://sites.google.com/view/0kzpsl33/home
https://sites.google.com/view/7vqzug72/home
https://sites.google.com/view/8qybcb91/home
https://sites.google.com/view/1manil34/home
https://sites.google.com/view/9zlzlw68/home
https://sites.google.com/view/7ytpgf83/home
https://sites.google.com/view/0figtg65/home
https://sites.google.com/view/3nphmi02/home
https://sites.google.com/view/0qkeih69/home
https://sites.google.com/view/1qqdjc96/home
https://sites.google.com/view/2ocmzl47/home
https://sites.google.com/view/0rszvm31/home
https://sites.google.com/view/8twpcf39/home
https://sites.google.com/view/1tmhcz01/home
https://sites.google.com/view/1fsimv87/home
https://sites.google.com/view/0krela31/home
https://sites.google.com/view/8jhshd10/home
https://sites.google.com/view/5tseou06/home
https://sites.google.com/view/2msyts76/home
https://sites.google.com/view/6dxuri73/home
https://sites.google.com/view/1pmboa56/home
https://sites.google.com/view/9iueuv34/home
https://sites.google.com/view/8pubxw30/home
https://sites.google.com/view/1tlyco56/home
https://sites.google.com/view/8srvbu36/home
https://sites.google.com/view/4gsnto37/home
https://sites.google.com/view/6akswp56/home
https://sites.google.com/view/2inxol47/home
https://sites.google.com/view/3oojsn55/home
https://sites.google.com/view/5mdqwb17/home
https://sites.google.com/view/7xuice12/home
https://sites.google.com/view/0qzfci43/home
https://sites.google.com/view/6ohonc26/home
https://sites.google.com/view/4tbmuv32/home
https://sites.google.com/view/1rbxss83/home
https://sites.google.com/view/2niebx01/home
https://sites.google.com/view/3qaeqy35/home
https://sites.google.com/view/0cbewx04/home
https://sites.google.com/view/3csyuh21/home
https://sites.google.com/view/8wylyx13/home
https://sites.google.com/view/1kpxse38/home
https://sites.google.com/view/8ovanb09/home
https://sites.google.com/view/6rmoih50/home
https://sites.google.com/view/5cfhmg25/home
https://sites.google.com/view/4ivxrt19/home
https://sites.google.com/view/4ltzqb02/home
https://sites.google.com/view/3vdlsy06/home
https://sites.google.com/view/5vwlbj78/home
https://sites.google.com/view/4naisw60/home

0 关注 分享

要回复文章请先登录注册