这里需要先说明的是:我拿到的数据是后台已经排好序的,所以我的目的是做滚动到某个高度时侧边栏的字母高亮与其内容对应,并且可以点击侧边栏的某个字母跳到列表对应的地方。


先看看实现后的效果,样式比较简陋:

Android字母索引通讯录 通讯录字母索引太小_字母侧边栏索引

Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_02



Android字母索引通讯录 通讯录字母索引太小_Android字母索引通讯录_03



是不是一眼就看出了侧边栏的字母表不全。是的。一开始我是做完整的26个字母+#,但是因为后台返回的列表内容并不一定包括26个字母+#,有的字母对应会出现无内容的情况,后面应产品的需求就改成了列表中有出现对应的字母才会显示。如果你需要做完整的,其实道理都一样,稍微转变一下就行了,这里我就不演示字母完整版的了。




首先看下html:


Android字母索引通讯录 通讯录字母索引太小_字母侧边栏索引_04


id为letter的就是侧边栏的字母,class为modal的就是点击后弹出当前所选字母。

这是侧边栏的样式


Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_05


这是弹出层的样式


Android字母索引通讯录 通讯录字母索引太小_字母侧边栏索引_06


pointer-events:none这个是CSS3比较实用的一个属性,设置为none以后,该属性不会成为鼠标事件的target,阻止点击产生任何效果。



下面就开始正式做了


Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_07



index就是当前的高亮字母,它字体是黑色且放大的,alphabet是完整的字母表加上#,下文我就直接称字母吧,其他变量我就不一一说明了,具体看注释吧,应该不难理解。



先通过接口获取数据,


Android字母索引通讯录 通讯录字母索引太小_Android字母索引通讯录_08



将后台返回的所有字母存入arr1数组中(这个拿到的不一定是完整的字母哦),然后调用我写好的一个方法getOffsetTops(),这是用于获取每个字母距离顶部的距离。


Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_09



然后我又调用另一个方法filterAlphabet(),


Android字母索引通讯录 通讯录字母索引太小_Android字母索引通讯录_10



我先说说filterAlphabet(),它的作用是将通过接口获取到的字母跟完整的字母做对比,如有一样的,就存入新的数组newArr中,如果你是只有一个列表那么你会觉得这个步骤很多余,我这样做的原因是,我的一个页面有5个列表都共用一个数组去渲染,所以我点击不同的列表拿到的数据都要去重置newArr。如果你只有一个列表那你可以跳过这个步骤。这时拿到准备渲染的newArr之后先把数组的第一个值赋给index,作用是索引列的第一个加上高亮效果。



变量offsetTops是什么呢?讲它之前我还要先说明ionItemGroup1,先在HTML循环遍历列表的地方写上#IonItemGroup1,ViewChildren是用来从视图中获取匹配的多个元素,返回的结果是一个QueryList集合,


Android字母索引通讯录 通讯录字母索引太小_Android字母索引通讯录_11



下面是我将ionItemGroup1打印出来的结果


Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_12


将每个字母距离顶部的距离放入offsetTops中,综上所述就完成了第一个步骤,offsetTops就是每个字母被内容撑开以后分别距离顶部的高度数组。


现在就可以开始做滚动处理:


Android字母索引通讯录 通讯录字母索引太小_字母侧边栏索引_13


ionic的内容组件ion-content提供了一个易使用的内容区,并且提供scrollToTop()方法来控制可滚动的区域,可以看看ionic官网文档ion-content


Android字母索引通讯录 通讯录字母索引太小_字母侧边栏索引_14



如果滚动高度小于第一个字母的高度,那么就将拿到的数组第一个值赋给index,如果滚动高度加上第一个字母的高度大于等于某个字母的高度,那么就将该字母赋值给index,这样就做到滚动的内容区与侧边栏高亮的字母同步了


this.ref.detectChanges()我标了一个框,它是用于手动检测变化的,我们要先import进来,


Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_15



ChangeDetectorRef是组件的变化检测器,我在组件中通过依赖注入的方式来获取该对象,具体的可以看官方文档ChangeDetectorRef,我需要用到的方法是detectChanges(),它的作用是从该组件到各个组件执行一次变化检测 ,这个比较适合用于频繁更新数据,量也大的列表,强制angular检查组件数据的变化。



说完滚动,那么就到点击事件了,点击右侧的单个字母,我们在点击的时候会从HTML中将点击的字母传进来,这时被点击的字母应该赋予高亮样式。然后再获取该字母在内容区距离顶部的距离,通过滑动到content对应的位置。


Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_16






与此同时,弹出层该出场了,如图所示

Android字母索引通讯录 通讯录字母索引太小_ionic通讯录_17

,点击的同时调用createModal(),让showModal为true显示出来,在加个定时器0.8秒后让它为false隐藏。