HarmonyOS鸿蒙Next中QQ音乐上面这条是怎么实现的

HarmonyOS鸿蒙Next中QQ音乐上面这条是怎么实现的 minibar是如何可以变换位置到上方的
因为minibar默认效果只有水平方向伸长推开页签栏
图片


更多关于HarmonyOS鸿蒙Next中QQ音乐上面这条是怎么实现的的实战教程也可以访问 https://www.itying.com/category-93-b0.html

17 回复

上面这个应该是自己实现的

更多关于HarmonyOS鸿蒙Next中QQ音乐上面这条是怎么实现的的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


但是这个材质跟官方效果一样的🙃官方没有单独开放材质而是只能用在hdstab和hdsnavigation上面…,

有需求的话可以走需求单

ok👌不过就是好奇因为已经用了minibar但是想自定义更多一点,

学习下

华为自带音乐布局感觉也还不错,

那个就是普通的minibar了,官方效果,

这不就是Stack布局吗

这是api23的那个hdstab实现的,但是我没见api里有能设置成这个样式的地方…,

应该是自己实现的上方的UI

QQ音乐也适配了鸿蒙的液态玻璃?(不太了解谅解),

自定义 View + 滚动监听 + 动画

可以详细讲一下吗?自定义view是什么意思?

图忘记裁了,是下面这里,图片从别人那里来的

图片

这两个Row固定在底部的话,可以实现了以后设置透明度,然后底层各个组件用List/Scroll包起来。或者直接Stack

鸿蒙Next中QQ音乐顶部的实现主要基于ArkUI框架。使用自定义组件结合状态管理实现动态布局,通过Flex或Grid布局管理器控制元素排列。顶部区域通常包含搜索框、用户头像等元素,采用Row容器水平排列。状态变量控制不同场景下的显示内容,如搜索状态切换、用户登录状态变化等。

在HarmonyOS Next中,QQ音乐顶部这种可动态变换位置的组件,其核心实现技术是ArkUI的“显隐控制与布局响应”,而非简单的minibar默认行为。它本质上是一个自定义的、状态驱动的容器组件

具体分析如下:

  1. 组件本质:这并非直接使用Minibar组件并改变其位置。Minibar的默认行为确实是在水平方向操作。要实现图示的垂直位置变换(从页面内部推至顶部),更合理的实现方式是自定义一个容器组件(如ColumnStack嵌套),内部包裹实际的内容区域和这个可变的“控制条”。

  2. 核心实现机制

    • 状态驱动:组件是否显示在顶部,由一个@State@Prop装饰的布尔变量控制(例如isPinnedToTop: boolean)。
    • 条件渲染:在布局中使用if/else或动态调整visibility属性,根据isPinnedToTop的值决定渲染哪个版本的“控制条”。
      • isPinnedToTopfalse时,该区域作为页面内容的一部分正常嵌入在滚动容器内。
      • isPinnedToToptrue时,在页面的顶层布局(如Stack的顶层或固定定位的Column中)渲染一个固定的控制条。
    • 布局与定位
      • 顶部固定模式:通常使用position: fixedalign约束将其固定在Stack的顶部。
      • 页面内嵌模式:作为普通内容节点存在于滚动容器中。
    • 交互与动画:监听页面的滚动事件(或内容区域的特定手势)。当滚动超过某个阈值时,通过状态变量触发布局切换。切换过程可以使用显式动画animateTo)来平滑过渡高度、透明度或位置属性,实现“推开”或“滑入”的视觉效果。
  3. 简要代码思路

@Entry
@Component
struct MusicPlayerPage {
  @State isControlBarPinned: boolean = false

  build() {
    Stack({ alignContent: Alignment.Top }) {
      Scroll() {
        Column() {
          if (!this.isControlBarPinned) {
            CustomControlBar()
          }
        }
        .onScroll((scrollOffset: number) => {
          if (scrollOffset > THRESHOLD) {
            this.isControlBarPinned = true
          } else {
            this.isControlBarPinned = false
          }
        })
      }

      if (this.isControlBarPinned) {
        CustomControlBar()
          .position({ x: 0, y: 0 })
          .width('100%')
          .zIndex(9)
          .transition({ type: TransitionType.Insert, opacity: 0.99 })
      }
    }
  }
}

总结:这个效果是通过监听滚动、状态管理、条件渲染与动画组合实现的定制化交互。开发者需要构建一个响应状态变化、在两种布局形态间切换的自定义组件,而非依赖单个组件的固有属性。

回到顶部