HarmonyOS Panel替代方案

Panel展示时底部组件不可操作,是否有替代方案。

HarmonyOS
2025-01-09 17:54:57
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zbw_apple

panel目前已废弃,后续不会继续演进了,建议使用bindSheet,参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-sheet-transition-V5#bindsheet

参考示例如下:

import { webview } from '@kit.ArkWeb';
import { display } from '@kit.ArkUI';

class MyModifier implements AttributeModifier<ColumnAttribute> {
  isFixed: boolean = false
  applyNormalAttribute(instance: ColumnAttribute): void {
    if (this.isFixed) {
      instance.offset({ y: 130 })
      instance.alignRules({
        top: {
          anchor: 'searchBox',
          'align': VerticalAlign.Bottom
        },
        right: { anchor: "__container__", align: HorizontalAlign.End }
      })
    } else {
      instance.alignRules({
        'bottom': {
          'anchor': 'ListScrollBox',
          'align': VerticalAlign.Top
        },
        right: { anchor: "__container__", align: HorizontalAlign.End }
      })
    }
  }
}
@Entry
@Component
struct PanelPage {
  controller: webview.WebviewController = new webview.WebviewController()
  listScroller: Scroller = new Scroller()
  @State isScroll: boolean = false
  @State currentLine: number = 0; //当前线路位置
  @State start: number = 0; //当前线路位置
  @State end: number = -1; //当前线路位置
  @State yStart: number = 0
  @State isUp: boolean = true
  @State showBg: boolean = false
  // list列表的最大高度
  maxHeight = px2vp(display.getDefaultDisplaySync().height) - 126
  screenHeight: number = px2vp(display.getDefaultDisplaySync().height) - 126
  @State bottomAvoidHeight: number = 30 //底部导航条高度
  @State @Watch('changeHeight') listHeight: number = 450; // list高度
  @State itemNumber: number = 0; // 列表显示第一项
  @State positionY: number = 0; // 列表的Y轴偏移量
  @State windowHeight: number = px2vp(display.getDefaultDisplaySync().height - 126 - 90) // window高度
  @State modifier: MyModifier = new MyModifier()

  changeHeight() {
    this.modifier.isFixed = this.listHeight > 450
  }

  aboutToAppear(): void {
  }

  build() {
    Stack({ alignContent: Alignment.Top }) {
      RelativeContainer() {
        // 线网图图
        Web({
          src: 'https://***.com/file/202008/metro-way/html/qdmetro3.html',
          controller: this.controller
        })
          .zoomAccess(true)
          .id('mapBox')

        if (this.showBg) {
          Row() {
          }
          .width('100%')
          .height('100%')
          .backgroundColor('#FF00A760')
          .id('bg')
          .transition(TransitionEffect.OPACITY.animation({ duration: 200 }))
          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
        }

        //顶部搜索框
        Row() {
          Image($r('app.media.ic_search')).width(22).height(22)
          Text('搜索目的地、地铁、公交').fontSize(15).fontColor('#FF666666').margin({ left: 8 })
        }
        .padding({ left: 18, right: 18 })
        .height(49)
        .margin({ top: 20, left: 16, right: 16 })
        .width('100%')
        .constraintSize({ maxWidth: '100%' })
        .borderWidth(1)
        .borderColor('#FFD6D6D6')
        .borderRadius(10)
        .backgroundColor('#FFFFFFFF')
        .alignRules({
          'top': { 'anchor': '__container', 'align': VerticalAlign.Top },
          'middle': { 'anchor': '__container', 'align': HorizontalAlign.Center },
        })
        .id('searchBox')
        .zIndex(1)

        Column() {
          Image($r('app.media.icon_line_location')).size({ width: 60, height: 60 })
            .onClick(() => {
            })
          Image($r('app.media.icon_line_download')).size({ width: 60, height: 60 })
            .onClick(() => {
            })
        }
        .height(120)
        .attributeModifier(this.modifier)
        .id('navBox')

        Row() {
          Image($r('app.media.ic_expand')).width(60).height(8)
        }.id('listBar')
        .alignRules({
          'bottom': {
            'anchor': 'ListScrollBox',
            'align': VerticalAlign.Top
          },
          middle: { anchor: "__container__", align: HorizontalAlign.Center }
        })
        
        List({ scroller: this.listScroller }) {
          ListItem() {
            Column().height(0.5).backgroundColor(Color.Transparent)
          }

          //附近站点
          ListItem() {
            Column() {
              Text('1')
            }
            .width('100%')
            .height(200)
            .backgroundColor('#FFF4F4F4')
            .borderRadius({ topLeft: 30, topRight: 30 })
            .pixelRound({
              start: PixelRoundCalcPolicy.FORCE_CEIL,
              top: PixelRoundCalcPolicy.FORCE_CEIL
            })
          }

          //购票查询
          ListItem() {
            Column() {
              Text('2')
            }.width('100%').height(200)
          }.backgroundColor('#FFF4F4F4')

          //起始位置,目的地
          ListItem() {
            Column() {
              Text('3')
            }.width('100%').height(200)
          }.backgroundColor('#FFF4F4F4')

          //失物招领
          ListItem() {
            Column() {
              Text('4')
            }.width('100%').height(200)
          }.backgroundColor('#FFF4F4F4')

          //地图
          ListItem() {
            Column() {
              Text('5')
            }.width('100%').height(200)
          }.backgroundColor('#FFF4F4F4')

          //爱心呼叫
          ListItem() {
            Column() {
              Text('6')
            }.width('100%').height(200)
          }.backgroundColor('#FFF4F4F4')
        }
        .backgroundColor(this.showBg ? '#FF00A760' : '#FFF4F4F4')
        .edgeEffect(EdgeEffect.None)
        .enableScrollInteraction(this.isScroll)
        .scrollBar(BarState.Off)
        .offset({ y: this.positionY })
        .width('100%')
        .height(this.listHeight)
        .id('ListScrollBox')
        .alignRules({
          'bottom': { 'anchor': '__container__', 'align': VerticalAlign.Bottom },
          'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start },
          'right': { 'anchor': '__container__', 'align': HorizontalAlign.End },
        })
        .onReachStart(() => {
          this.itemNumber = 0;
        })
        .onScrollIndex((start: number) => {
          this.itemNumber = start;
        })
        .onTouch((event: TouchEvent) => {
          switch (event.type) {
          // 手指按下触摸屏幕
            case TouchType.Down: {
              this.yStart = event.touches[0].y;
              break;
            }
          // 手指在屏幕滑动
            case TouchType.Move: {
              const yEnd = event.touches[0].y; // 手指离开屏幕的纵坐标
              const height = Math.abs(Math.abs(yEnd) - Math.abs(this.yStart)); // 手指在屏幕上的滑动距离
              const maxHeight = this.windowHeight - 49 - 20 // 设置list最大高度
              // 判断上滑,且list跟随手势滑动
              if (yEnd <= this.yStart) {
                this.isUp = true;
                const temHeight = this.listHeight + height;
                if (temHeight >= maxHeight) {
                  this.isScroll = true;
                  this.showBg = true;
                  this.listHeight = maxHeight;
                } else {
                  this.isScroll = false;
                  this.listHeight = temHeight;
                }
              }
              // 判断下滑,且list跟随手势滑动
              else {
                this.isUp = false;
                const temHeight = this.listHeight - height;
                if (this.itemNumber === 0) {
                  // 列表高度随滑动高度变化
                  this.listHeight = temHeight;
                } else {
                  this.listHeight = maxHeight;
                }
                this.showBg = false;
              }
              this.yStart = event.touches[0].y;
              break;
            }

          // 手指离开屏幕
            case TouchType.Up: {
              const maxHeight = this.windowHeight - 49 - 20 // 设置list最大高度
              // 列表上滑时,分阶段滑动
              if (this.isUp) {
                // 分阶段滑动,当list高度位于第一个item和第二个item之间时,滑动到第二个item
                if (this.listHeight > 78 && this.listHeight <= 450 + this.bottomAvoidHeight) {
                  this.listHeight = 450
                  this.isScroll = false;
                  this.showBg = false;
                  return;
                }
                // 分阶段滑动,当list高度位于顶部和第二个item之间时,滑动到页面顶部
                else if (450 + this.bottomAvoidHeight < this.listHeight && this.listHeight <= maxHeight) {
                  this.listHeight = maxHeight;
                  this.isScroll = true;
                  this.showBg = true;
                  return;
                }
              }
              // 列表下滑时,分阶段滑动
              else {
                // full
                if (this.listHeight === maxHeight) {
                  this.showBg = true;
                  this.listHeight = maxHeight;
                }
                // 分阶段滑动,half
                else if (this.listHeight >= 450 + this.bottomAvoidHeight && this.listHeight <= maxHeight) {
                  this.listHeight = 450
                  this.showBg = false;
                  this.isScroll = false;
                  return;
                }
                // 分阶段滑动,min
                else if (this.listHeight < 450 + this.bottomAvoidHeight || this.listHeight <= 78) {
                  this.listHeight = 78;
                  this.showBg = false;
                  this.isScroll = false;
                  return;
                }
              }
            }
          }
        })
        .animation({
          duration: 300, // 动画持续时间,单位毫秒
          curve: Curve.Friction, // 动画曲线
          iterations: 1, // 动画播放次数
          playMode: PlayMode.Normal// 动画播放模式
        })
      }
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
    }
    .width('100%')
    .height('100%')
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
  }
}
分享
微博
QQ
微信
回复
2025-01-09 19:51:09
相关问题
HarmonyOS JSONObject替代方案
426浏览 • 2回复 待解决
HarmonyOS netty替代方案
544浏览 • 1回复 待解决
ImageReader 在HarmonyOS替代方案
1939浏览 • 1回复 待解决
HarmonyOS scheme是否有替代方案
714浏览 • 1回复 待解决
HarmonyOS bind(this)问题的替代方案
442浏览 • 1回复 待解决
GlobalThis替代方案有哪些?
1283浏览 • 1回复 待解决
HarmonyOS import相对路径有无替代方案
378浏览 • 1回复 待解决
在鸿蒙中netty有好的替代方案
406浏览 • 0回复 待解决
图像处理库是否有替代的解决方案
739浏览 • 0回复 待解决
HarmonyOS Panel 设置 borderRadius 不生效
1327浏览 • 1回复 待解决