ArkTs中 list()组件 和 AlphabetIndexer()组件,用两个就可以轻松实现一个简易通讯录。
大概思路
- list()组件 负责数据渲染 布局 滚动 获取 ListItemGroup索引值
- AlphabetIndexer()组件 负责 字母表与数据的交互
联系人数据
由于我们主要实现的是通讯录,数据就放这里
hotCitys: string[] =
['北京', '上海', '广州', '深圳', '天津', '杭州', '南京', '苏州', '成都', '武汉', '重庆', '西安', '香港', '澳门',
'台北']
historyCitys: string[] = ['北京', '上海', '广州', '深圳', '重庆']
cityContentList: BKCityContent[] = [
{
initial: 'A',
cityNameList: ['阿拉善', '鞍山', '安庆', '安阳', '阿坝', '安顺']
},
{
initial: 'B',
cityNameList: ['北京', '保定', '包头', '巴彦淖尔', '本溪', '白山']
},
{
initial: 'C',
cityNameList: ['成都', '重庆', '长春', '长沙', '承德', '沧州']
},
{
initial: 'D',
cityNameList: ['大连', '东莞', '大同', '丹东', '大庆', '大兴安岭']
},
{
initial: 'E',
cityNameList: ['鄂尔多斯', '鄂州', '恩施', '额尔古纳市', '二连浩特市', '恩施市']
},
{
initial: 'F',
cityNameList: ['福州', '佛山', '抚顺', '阜新', '阜阳', '抚州']
},
{
initial: 'G',
cityNameList: ['广州', '贵阳', '赣州', '桂林', '贵港', '广元']
},
{
initial: 'H',
cityNameList: ['杭州', '海口', '哈尔滨', '合肥', '呼和浩特', '邯郸']
},
{
initial: 'J',
cityNameList: ['济南', '晋城', '晋中', '锦州', '吉林', '鸡西']
},
{
initial: 'K',
cityNameList: ['昆明', '开封', '康定市', '昆山', '康保县', '宽城满族自治县']
},
{
initial: 'L',
cityNameList: ['兰州', '廊坊', '临汾', '吕梁', '辽阳', '辽源']
},
{
initial: 'M',
cityNameList: ['牡丹江', '马鞍山', '茂名', '梅州', '绵阳', '眉山']
},
{
initial: 'N',
cityNameList: ['南京', '宁波', '南昌', '南宁', '南通', '南平']
},
{
initial: 'P',
cityNameList: ['盘锦', '莆田', '萍乡', '平顶山', '濮阳', '攀枝花']
},
{
initial: 'Q',
cityNameList: ['青岛', '秦皇岛', '齐齐哈尔', '七台河', '衢州', '泉州']
},
{
initial: 'R',
cityNameList: ['日照', '日喀则', '饶阳县', '任丘市', '任泽区', '饶河县']
},
{
initial: 'S',
cityNameList: ['上海', '苏州', '深圳', '沈阳', '石家庄', '朔州']
},
{
initial: 'T',
cityNameList: ['天津', '太原', '唐山', '通辽', '铁岭', '通化']
},
{
initial: 'W',
cityNameList: ['无锡', '武汉', '乌海', '乌兰察布', '温州', '芜湖']
},
{
initial: 'X',
cityNameList: ['厦门', '西安', '西宁', '邢台', '忻州', '兴安盟']
},
{
initial: 'Y',
cityNameList: ['扬州', '阳泉', '运城', '营口', '延边', '伊春']
},
{
initial: 'Z',
cityNameList: ['郑州', '珠海', '张家口', '镇江', '舟山', '漳州']
}
]
alphabets: string[] =
['#', '热', "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "W", "X", "Y",
"Z"]
页面布局
通讯录,我们通常用state()层叠布局来包裹两个组件,state()有个属性可以把AlphabetIndexer()组件 的位置安排到页面右边。用list()组件 配合 ForEach()循环来实现页面布局。
Stack({alignContent:Alignment.End}) {
//通讯录
List({scroller:this.scroller}) {
this.history()
this.hot()
this.signal()
}
.onScrollIndex((start:number)=>{
this.curren = start
})
.width('100%')
//字母表
AlphabetIndexer({arrayValue:this.alphabets,
selected:this.curren
})
.itemSize(28)
.font({size:15})
.selectedFont({size:18})
.onSelect((index)=>{
this.scroller.scrollToIndex(index)
})
}
list()组件
历史数据
@Builder
history(){
ListItemGroup({ header: this.mygroup('历史') }) {
ListItem() {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.historyCitys, (item: string) => {
Text(item)
.textAlign(TextAlign.Center)
.margin({top:10,bottom:10})
.width('33%')
})
}
.padding(10)
.width('100%')
}
}
.width('100%')
}
热门城市
@Builder
hot(){
ListItemGroup({ header: this.mygroup('热门城市') }) {
ListItem() {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.hotCitys, (item: string) => {
Text(item)
.textAlign(TextAlign.Center)
.margin({top:10,bottom:10})
.width('33%')
})
}
.padding(10)
.width('100%')
}
}
.width('100%')
}
字母城市 通过双重ForEach循环来实现页面基本布局
@Builder
signal(){
ForEach(this.cityContentList,(item:BKCityContent,index)=>{
ListItemGroup({header:this.mygroup(item.initial)}) {
ForEach(item.cityNameList, (item1: string, index) => {
ListItem() {
Text(item1)
.fontSize(20)
.margin({ top: 8, bottom: 8 })
}
})
}
.divider({strokeWidth:2})
})
}
通过创建控制器来获取listItemGroup开始的索引值
struct Index {
//创建控制器
scroller:ListScroller = new ListScroller()
build() {
Stack({alignContent:Alignment.End}) {
//设置给list组件
List({scroller:this.scroller}) {
this.history()
this.hot()
this.signal()
}
//获取listItemGroup开始的索引值
.onScrollIndex((start:number)=>{
//将获取开始的索引值赋值给 curren 来实现与 AlphabetIndexer 交互
this.curren = start
})
.width('100%')
}
AlphabetIndexer()组件
通过获取listItemGroup开始的索引值来实现双方交互
AlphabetIndexer({arrayValue:this.alphabets,
selected:this.curren//选中下标高亮
})
.itemSize(28)
.font({size:15})
.selectedFont({size:18})
.onSelect((index)=>{
//index 字母表的下标
// 控制List滚动
this.scroller.scrollToIndex(index)
})
整体代码以及运行效果
interface BKCityContent {
initial: string
cityNameList: string[]
}
@Entry
@Component
struct Index {
scroller:ListScroller = new ListScroller()
hotCitys: string[] =
['北京', '上海', '广州', '深圳', '天津', '杭州', '南京', '苏州', '成都', '武汉', '重庆', '西安', '香港', '澳门',
'台北']
historyCitys: string[] = ['北京', '上海', '广州', '深圳', '重庆']
cityContentList: BKCityContent[] = [
{
initial: 'A',
cityNameList: ['阿拉善', '鞍山', '安庆', '安阳', '阿坝', '安顺']
},
{
initial: 'B',
cityNameList: ['北京', '保定', '包头', '巴彦淖尔', '本溪', '白山']
},
{
initial: 'C',
cityNameList: ['成都', '重庆', '长春', '长沙', '承德', '沧州']
},
{
initial: 'D',
cityNameList: ['大连', '东莞', '大同', '丹东', '大庆', '大兴安岭']
},
{
initial: 'E',
cityNameList: ['鄂尔多斯', '鄂州', '恩施', '额尔古纳市', '二连浩特市', '恩施市']
},
{
initial: 'F',
cityNameList: ['福州', '佛山', '抚顺', '阜新', '阜阳', '抚州']
},
{
initial: 'G',
cityNameList: ['广州', '贵阳', '赣州', '桂林', '贵港', '广元']
},
{
initial: 'H',
cityNameList: ['杭州', '海口', '哈尔滨', '合肥', '呼和浩特', '邯郸']
},
{
initial: 'J',
cityNameList: ['济南', '晋城', '晋中', '锦州', '吉林', '鸡西']
},
{
initial: 'K',
cityNameList: ['昆明', '开封', '康定市', '昆山', '康保县', '宽城满族自治县']
},
{
initial: 'L',
cityNameList: ['兰州', '廊坊', '临汾', '吕梁', '辽阳', '辽源']
},
{
initial: 'M',
cityNameList: ['牡丹江', '马鞍山', '茂名', '梅州', '绵阳', '眉山']
},
{
initial: 'N',
cityNameList: ['南京', '宁波', '南昌', '南宁', '南通', '南平']
},
{
initial: 'P',
cityNameList: ['盘锦', '莆田', '萍乡', '平顶山', '濮阳', '攀枝花']
},
{
initial: 'Q',
cityNameList: ['青岛', '秦皇岛', '齐齐哈尔', '七台河', '衢州', '泉州']
},
{
initial: 'R',
cityNameList: ['日照', '日喀则', '饶阳县', '任丘市', '任泽区', '饶河县']
},
{
initial: 'S',
cityNameList: ['上海', '苏州', '深圳', '沈阳', '石家庄', '朔州']
},
{
initial: 'T',
cityNameList: ['天津', '太原', '唐山', '通辽', '铁岭', '通化']
},
{
initial: 'W',
cityNameList: ['无锡', '武汉', '乌海', '乌兰察布', '温州', '芜湖']
},
{
initial: 'X',
cityNameList: ['厦门', '西安', '西宁', '邢台', '忻州', '兴安盟']
},
{
initial: 'Y',
cityNameList: ['扬州', '阳泉', '运城', '营口', '延边', '伊春']
},
{
initial: 'Z',
cityNameList: ['郑州', '珠海', '张家口', '镇江', '舟山', '漳州']
}
]
alphabets: string[] =
['#', '热', "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "W", "X", "Y",
"Z"]
@State curren:number = 0
@Builder
mygroup(titles: string) {
Text(titles)
.fontSize(23)
.fontColor(Color.Gray)
}
@Builder
history(){
ListItemGroup({ header: this.mygroup('历史') }) {
ListItem() {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.historyCitys, (item: string) => {
Text(item)
.textAlign(TextAlign.Center)
.margin({top:10,bottom:10})
.width('33%')
})
}
.padding(10)
.width('100%')
}
}
.width('100%')
}
@Builder
hot(){
ListItemGroup({ header: this.mygroup('热门城市') }) {
ListItem() {
Flex({ wrap: FlexWrap.Wrap }) {
ForEach(this.hotCitys, (item: string) => {
Text(item)
.textAlign(TextAlign.Center)
.margin({top:10,bottom:10})
.width('33%')
})
}
.padding(10)
.width('100%')
}
}
.width('100%')
}
@Builder
signal(){
ForEach(this.cityContentList,(item:BKCityContent,index)=>{
ListItemGroup({header:this.mygroup(item.initial)}) {
ForEach(item.cityNameList, (item1: string, index) => {
ListItem() {
Text(item1)
.fontSize(20)
.margin({ top: 8, bottom: 8 })
}
})
}
.divider({strokeWidth:2})
})
}
build() {
Stack({alignContent:Alignment.End}) {
List({scroller:this.scroller}) {
this.history()
this.hot()
this.signal()
}
//获取listItemGroup开始的索引值
.onScrollIndex((start:number)=>{
this.curren = start
})
.width('100%')
AlphabetIndexer({arrayValue:this.alphabets,
selected:this.curren//选中下标高亮
})
.itemSize(28)
.font({size:15})
.selectedFont({size:18})
.onSelect((index)=>{ //index 字母表的下标
// 控制滚动
this.scroller.scrollToIndex(index)
})
}
}
}
运行
最后
本篇到此结束,感谢大家的支持,我们下次再见! 👋