《解决界面交互痛点:WaterFlow 瀑布流、双层嵌套滚动、键盘避让与跨 Ability 跳转实践》

1. WaterFlow瀑布流

瀑布流布局的特点:

每一列盒子的宽度一致, 盒子的高度不一致

自上而下, 形成参差错落效果

waterFlow和Grid布局类似,都支持columnsTemplate和rowsTemplate通过 fr 的形式对行和列进行分割

常用参数{ }

  • footer 设置WaterFlow尾部组件。(抽取@Builder)
  • scroller 可滚动组件的控制器,与可滚动组件绑定

不允许和其他滚动类组件,如:List、Grid、Scroll等绑定同一个滚动控制对象。

常用属性

  • .columnsTemplate('1fr 1fr') 设置列
  • .rowsTemplate('1fr 1fr') 设置行
  • .columnsGap(10) 列间隙
  • .rowsGap(10) 行间隙
  • .edgeEffect 边缘滚动效果 edgeEffect(EdgeEffect. ) Spring 弹簧效果
  • .scrollBar 设置滚动条状态 默认值:BarState.Off
javascript 复制代码
@Entry
@Component
struct WaterFlowCase {
  build() {
    // 顶级容器
    WaterFlow() {
      // 子组件 -> 有且只能有一个根组件
      FlowItem() {
        // 内容
      }
    }
    .columnsTemplate("1fr 1fr 1fr")
    .columnsGap(20)
    .rowsGap(20)
    .padding(20)
  }
}
javascript 复制代码
import { promptAction } from '@kit.ArkUI'

@Entry
@Component
struct WaterFlowPage {
  build() {
    Column() {
      // 瀑布流基本使用
      // footer  到底了 显示的内容
      WaterFlow({ footer: this.footerBuilder() }) {
        ForEach(Array.from({ length: 10 }), () => {
          FlowItem() {
            Column() {
              Text('瀑布流')
                .fontSize(30)
            }
          }
          .width('100%')
          .height(50 * Math.floor(Math.random() * 10))
          .backgroundColor(Color.Pink)
        })
      }
      .columnsTemplate('1fr 1fr') //分割的数量
      .columnsGap(10) //间隔距离
      .rowsGap(10) //间隔距离
      // 触底时 触发事件 可在此发送请求加载数据
      .onReachEnd(() => {
        promptAction.openToast({
          message: '努力加载中...',
        })
      })
    }
    .height('100%')
    .width('100%')
  }
  @Builder
  footerBuilder() {
    Text('到底了~')
  }
}

2. 双层嵌套滚动

父容器滚动 - 例如 : Scroll

子容器滚动 - 例如 : List

.nestedScroll({

scrollForward: NestedScrollMode.PARENT_FIRST, //上滑动 父组件优先

scrollBackward: NestedScrollMode.SELF_FIRST // 向下滑动 自己优先

})

javascript 复制代码
// 父组件
@Entry
@Component
struct QianTaoHuaDong {
  build() {
    Column() {
      Scroll() {
        Column({ space: 10 }) {
          Swiper() {
            Text('1')
              .styleTEXT(Color.Pink)
            Text('2')
              .styleTEXT(Color.Blue)
            Text('3')
              .styleTEXT(Color.Red)
          }

          Column() {
            itemList()
          }
        }
      }
    }
    .height('100%')
    .width('100%')
  }
}

@Extend(Text)
function styleTEXT(color: Color) {
  .width('100%')
  .height(120)
  .padding({ left: 10, right: 10 })
  .backgroundColor(color)
}
// 子组件
@Component
struct itemList {
  build() {
    List() {
      ForEach(Array.from({ length: 10 }), () => {
        ListItem() {
          Text('12345')
        }
        .width('100%')
        .height(100)
        .backgroundColor(Color.Orange)
      })
    }
    .divider({ strokeWidth: 10 })
    .scrollBar(BarState.Off)
    .layoutWeight(1)
    // 不是list特有的属性,滚动组件都可设置,嵌套组件中 把他设置给  子组件
    .nestedScroll({
      scrollForward: NestedScrollMode.PARENT_FIRST, //上滑动 父组件优先
      scrollBackward: NestedScrollMode.SELF_FIRST  //向下滑动 自己优先
    })
  }
}

3. 键盘避让

复制代码
import { KeyboardAvoidMode } from '@kit.ArkUI'//需要手动引入

 aboutToAppear(): void {
   // 设置软键盘弹出时界面的调整策略  setKeyboardAvoidMode
   // KeyboardAvoidMode.RESIZE是鸿蒙提供的枚举值,表示键盘弹出时自动调整界面布局
    this.getUIContext().setKeyboardAvoidMode( KeyboardAvoidMode.RESIZE)
  }
javascript 复制代码
import { KeyboardAvoidMode } from '@kit.ArkUI'//需要手动引入,不会自动引入

@Entry
@Component
struct JianPanBiRang {
  aboutToAppear(): void {
    // 软键盘弹起避让------压缩模式
    this.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE)
  }

  build() {
    Column() {
      Column() {
        Row({ space: 10 }) {
          Image($r('app.media.ic_public_arrow_down'))
            .width(20)
            .aspectRatio(1)
          Text('在干撒')
        }
        .width('100%')
        .justifyContent(FlexAlign.Start)

        Row({ space: 10 }) {
          Text('敲代码')
          Image($r('app.media.ic_public_arrow_down'))
            .width(20)
            .aspectRatio(1)
        }
        .width('100%')
        .justifyContent(FlexAlign.End)
      }
      .layoutWeight(1)

      TextInput()
        .backgroundColor(Color.Brown)
    }
    .height('100%')
    .width('100%')
    .padding(20)
  }
}

4. 跨ability跳转

Ability名称查看位置

4.1. 同一个项目 - ability跳转

javascript 复制代码
import { common } from '@kit.AbilityKit'

  Button('跳转XXXX')
.onClick(() => {
          // 1、获取UIAbilityContext应用上下文
          const ctx = this.getUIContext().getHostContext() as common.UIAbilityContext
          
          // 2、唤起其他的ability窗口
          ctx.startAbility({
            bundleName: 'com.example.my_base', //应用的包名
            abilityName: 'ShiPinHao'  //ability的名称
          })
        })
javascript 复制代码
import { common } from '@kit.AbilityKit'

AppStorage.setOrCreate('name', '参数:12')

@Entry
@Component
struct WeiXinPage {
  build() {
    Column() {
      Text('微信聊天')
        .fontSize(30)
        .margin({ top: 50 })
      
      Button('跳转到视频号')
        .onClick(() => {
          // 获取UIAbilityContext应用上下文
          const ctx = this.getUIContext().getHostContext() as common.UIAbilityContext
          
          //   唤起其他的ability窗口
          ctx.startAbility({
            bundleName: 'com.example.my_base', //应用的包名
            abilityName: 'ShiPinHao'  //ability的名称
          })
        })
    }
    .height('100%')
    .width('100%')
  }
}
javascript 复制代码
@Entry
@Component
struct Index {
  @StorageLink('name')
  name: string = ''

  build() {
    Column({ space: 20 }) {
      Text('视频号')
        .fontSize(30)
      Text(this.name)
        .fontSize(30)
    }
    .height('100%')
    .width('100%')
  }
}

4.2. 不同项目 - ability跳转

前提:保证两个项目都是运行状态

javascript 复制代码
import { common } from '@kit.AbilityKit'
import { promptAction } from '@kit.ArkUI'


@Entry
@Component
struct ChePiaoPage {
  build() {
    Column() {
      Text('12306购票')
        .fontSize(30)
      Button('去支付宝支付')
        .onClick(async () => {
          const ctx = this.getUIContext().getHostContext() as common.UIAbilityContext
          const res = await ctx.startAbilityForResult({
            bundleName: 'com.example.my_base02', //需要跳转到的项目  包名
            abilityName: 'EntryAbility', //需要跳转到的项目  Ability名称
            moduleName: 'entry', //需要跳转到的项目 模块名称
            //传递参数
            parameters: {
              'money': 299.00
            }
          })
          // 接受参数
          if (res.want?.parameters) {
            if (res.want.parameters['success']) {
              promptAction.openToast({
                message: '支付成功~',
                bottom: 300
              })
            }
          }
        })
    }
    .height('100%')
    .width('100%')
  }
}
javascript 复制代码
import { common } from '@kit.AbilityKit'

@Entry
@Component
struct Index {
  @StorageLink('money')
  money: number = 0

  build() {
    Column() {
      Text('支付宝界面')
        .fontSize(30)
      Text('待支付的金额为' + this.money + '元')
        .fontSize(20)

      Button('输入支付密码')
        .onClick(() => {
          const ctx = this.getUIContext().getHostContext() as common.UIAbilityContext
          ctx.terminateSelfWithResult({
            // 返回时,必须写want和resultCode,不可省略
            want: {
              bundleName: 'com.example.my_base', //包名
              abilityName: 'EntryAbility', //ability的模块
              parameters: { 'success': true }//返回时携带的参数
            },
            resultCode: 0//必须写(返回的结果的code)
          })
        })
    }
    .height('100%')
    .width('100%')
  }
}
相关推荐
ifeng09186 小时前
HarmonyOS分布式任务调度——跨设备智能任务分配与迁移
分布式·华为·harmonyos
鸿蒙小白龙10 小时前
OpenHarmony蓝牙技术全解析:从设备发现到数据传输的完整流程
harmonyos·鸿蒙·鸿蒙系统·open harmony
shenshizhong12 小时前
鸿蒙HDF框架源码分析
前端·源码·harmonyos
宇宙最强的无天佛祖16 小时前
鸿蒙开发中快速获取相册图片的缩略图
harmonyos
冰冷的bin17 小时前
【Harmony】鸿蒙相机拍照使用简单示例
数码相机·华为·harmonyos
爱笑的眼睛1121 小时前
HarmonyOS RemoteWindow远程窗口组件的分布式能力深度解析
华为·harmonyos
爱笑的眼睛111 天前
HarmonyOS Badge徽标组件:深入消息提示的实现与优化
华为·harmonyos
爱笑的眼睛111 天前
HarmonyOS List组件性能优化:从基础到高级实践
华为·harmonyos
ifeng09181 天前
HarmonyOS实战项目:打造智能家居控制中心(设备发现与控制)
wpf·智能家居·harmonyos