字母表与侧标滚动栏的双向绑定

字母表与侧标滚动栏的双向绑定

HarmonyOS
2024-05-26 15:51:10
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
flyCloud00

构建一个侧边导航的列表页,实现列表与导航的双向绑定效果:左侧列表滑动,右侧导航栏自动定位;点击右侧导航栏,左侧列表自动定位。

下面,我们利用List组件和AlphabetIndexer组件来实现一个联系人列表的效果。

左侧红框内使用List组件,右侧红框内使用AlphabetIndexer组件。

使用

1. 创建一个新的page页面。

2. 构建页面中联系人的数据。

3. 定义一个联系人类,每一个联系人类中包含一个序号和一个姓名组。页面中联系人的数据使用联系人对象数组来实现。

// 联系人类 
class Contacts { 
  constructor(index: string, names: string[]) { 
    this.index = index 
    this.names = names 
  } 
 
  index: string // 序号 
  names: string[] // 姓名组 
} 
 
// 姓名组 
names: string[] = ["name1", "name2", "name3", "name4", "name5"] 
// 联系人对象数组 
contacts: Contacts[] = [ 
  new Contacts('A', this.names), 
  new Contacts('B', this.names), 
  new Contacts('C', this.names), 
  new Contacts('D', this.names), 
  new Contacts('E', this.names), 
  new Contacts('F', this.names), 
  new Contacts('G', this.names), 
  new Contacts('H', this.names), 
  new Contacts('I', this.names), 
  new Contacts('J', this.names), 
  new Contacts('K', this.names), 
  new Contacts('L', this.names), 
  new Contacts('M', this.names), 
  new Contacts('N', this.names), 
  new Contacts('O', this.names), 
  new Contacts('P', this.names), 
  new Contacts('Q', this.names), 
  new Contacts('R', this.names), 
  new Contacts('S', this.names), 
  new Contacts('T', this.names), 
  new Contacts('U', this.names), 
  new Contacts('V', this.names), 
  new Contacts('W', this.names), 
  new Contacts('X', this.names), 
  new Contacts('Y', this.names), 
  new Contacts('Z', this.names), 
]

4.构建导航栏的数据。

value: string[] = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

5.构建左侧联系人列表。

定义flag变量,使用@State修饰,当flag变量发生变化时,能触发页面刷新。

通过List组件的onScrollIndex滚动事件,当List发生滚动时,flag变量能接收当前页面位置的索引值。

@State flag: number = 0 // 绑定AlphabetIndexer的index 
scroller: Scroller = new Scroller() // list 滚动控制 
// 左侧联系人列表 
List({ space: 20, initialIndex: 0, scroller: this.scroller }) {  
// 使用scroller滚动控制   
ForEach(this.contacts, (value) => { 
    ListItem() { 
      Column() { 
        Text('' + value.index) 
          .fontSize(30) 
          .textAlign(TextAlign.Center).backgroundColor(0xFFFFFF) 
        ForEach(value.names, (name: string) => { 
          Column({ space: 10 }) { 
            Text('' + name) 
              .fontSize(20) 
              .textAlign(TextAlign.Center).backgroundColor(0xFFFFFF) 
          } 
        }) 
      } 
    } 
  }) 
}.width('80%') 
.backgroundColor(Color.Gray) 
.listDirection(Axis.Vertical) // 排列方向 
.onScrollIndex((firstIndex: number, lastIndex: number) => { 
 // 发生滚动的事件 
  this.flag = firstIndex // 刷新 AlphabetIndexer 的位置 
})

 6.构建右侧导航栏。

AlphabetIndexer组件的selected参数使用之前定义的flag变量,可以实现当flag变量发生变化时,导航栏定位到对应索引的位置。

通过AlphabetIndexer组件的onSelect选择事件,当导航栏被点击时,使用list组件绑定的scroller的scrollToIndex方法,让list滚动到指定的索引位置。

说明:List组件与AlphabetIndexer组件中是根据索引值来定位,也就是元素在数组的中的位置值,与元素本身的值没有关系。

// 右侧导航列 
AlphabetIndexer({ arrayValue: this.value, selected: this.flag }) 
  .width("20%") 
  .font({ size: 20, weight: FontWeight.Bold }) // 字体设置 
  .selectedColor(Color.Blue) // 选中颜色 
  .selectedBackgroundColor(0xCCCCCC) // 选中背景颜色 
  .usingPopup(true) // 是否显示弹出框 
  .selectedFont({ size: 28, weight: FontWeight.Bolder }) // 选中的样式 
  .itemSize(30) // 每一项的大小正方形 
  .alignStyle(IndexerAlign.Left) // 支持弹窗显示在索引条右侧和左侧 
  .onSelect((index: number) => { 
 // 点击的事件 
    console.info(`AlphabetIndexer 选中了 ${this.value[index]}`) // 选中的事件 
    this.flag = index 
    this.scroller.scrollToIndex(this.flag) // list滚动到指定索引的位置 
  })

全量代码:

class Contacts { 
  constructor(index: string, names: string[]) { 
    this.index = index 
    this.names = names 
  } 
  index: string // 序号 
  names: string[] // 姓名组 
} 
// list与list侧边导航栏的实现,双向绑定 
@Entry 
@Componentstruct 
 AlphabetIndexerTest { 
  names: string[] = ["name1", "name2", "name3", "name4", "name5"] 
  @State contacts: Contacts[] = [ 
    new Contacts('A', this.names), 
    new Contacts('B', this.names), 
    new Contacts('C', this.names), 
    new Contacts('D', this.names), 
    new Contacts('E', this.names), 
    new Contacts('F', this.names), 
    new Contacts('G', this.names), 
    new Contacts('H', this.names), 
    new Contacts('I', this.names), 
    new Contacts('J', this.names), 
    new Contacts('K', this.names), 
    new Contacts('L', this.names), 
    new Contacts('M', this.names), 
    new Contacts('N', this.names), 
    new Contacts('O', this.names), 
    new Contacts('P', this.names), 
    new Contacts('Q', this.names), 
    new Contacts('R', this.names), 
    new Contacts('S', this.names), 
    new Contacts('T', this.names), 
    new Contacts('U', this.names), 
    new Contacts('V', this.names), 
    new Contacts('W', this.names), 
    new Contacts('X', this.names), 
    new Contacts('Y', this.names), 
    new Contacts('Z', this.names), 
  ] 
  scroller: Scroller = new Scroller() // list 滚动控制 
  value: string[] = [ 
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 
    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] 
  @State flag: number = 0 // 绑定AlphabetIndexer的index 
  build() { 
    Row() { 
      // 左侧联系人列表 
      List({ space: 20, initialIndex: 0, scroller: this.scroller }) { 
 // 使用scroller滚动控制 
        ForEach(this.contacts, (value) => { 
          ListItem() { 
            Column() { 
              Text('' + value.index) 
                .fontSize(30) 
                .textAlign(TextAlign.Center).backgroundColor(0xFFFFFF) 
              ForEach(value.names, (name: string) => { 
                Column({ space: 10 }) { 
                  Text('' + name) 
                    .fontSize(20) 
                    .textAlign(TextAlign.Center).backgroundColor(0xFFFFFF) 
                } 
              }) 
            } 
          } 
        }) 
      } 
      .width('80%') 
      .backgroundColor(Color.Gray) 
      .listDirection(Axis.Vertical) // 排列方向 
      .onScrollIndex((firstIndex: number, lastIndex: number) => { 
      // 发生滚动的事件 
        this.flag = firstIndex // 刷新 AlphabetIndexer 
      }) 
      // 右侧导航列 
      AlphabetIndexer({ arrayValue: this.value, selected: this.flag }) 
        .width("20%") 
        .font({ size: 20, weight: FontWeight.Bold }) // 字体设置 
        .selectedColor(Color.Blue) // 选中颜色 
        .selectedBackgroundColor(0xCCCCCC) // 选中背景颜色 
        .usingPopup(true) // 是否显示弹出框 
        .selectedFont({ size: 28, weight: FontWeight.Bolder }) // 选中的样式 
        .itemSize(30) // 每一项的大小正方形 
        .alignStyle(IndexerAlign.Left) // 支持弹窗显示在索引条右侧和左侧 
        .onSelect((index: number) => { 
          // 点击的时间 
          console.info(`AlphabetIndexer 选中了 ${this.value[index]}`) // 选中的事件 
          this.flag = index 
          this.scroller.scrollToIndex(this.flag) // list滚动到指定索引的位置 
        }) 
    }.width("100%") 
  } 
}
分享
微博
QQ
微信
回复
2024-05-27 21:03:32
相关问题
HarmonyOS 滑返回事件拦截绑定
1206浏览 • 1回复 待解决
HarmonyOS $$双向绑定问题
280浏览 • 1回复 待解决
HarmonyOS 无法使用$$双向绑定
821浏览 • 1回复 待解决
HarmonyOS如何实现双向数据绑定
448浏览 • 1回复 待解决
ArkTS简单类型变量双向数据绑定
1478浏览 • 1回复 待解决
获取状态导航高度
636浏览 • 1回复 待解决
ArkTSNative分别如何动态加载SO库
2456浏览 • 1回复 待解决
HarmonyOS Tabs组件Tab滚动问题
531浏览 • 1回复 待解决
ArkTSNative如何进行map数据交互
2236浏览 • 1回复 待解决
父组件子组件使用@Link双向同步
919浏览 • 1回复 待解决
鸿蒙如何获取设备绑定设备ID?
987浏览 • 1回复 待解决
如何获取状态导航高度?
228浏览 • 0回复 待解决
HarmonyOS 请问TabContent如何page绑定
615浏览 • 1回复 待解决