自定义通讯录字母索引

2024-05-27 01:48

本文主要是介绍自定义通讯录字母索引,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、先来看下布局的效果

布局的代码如下,其中LetterIndexView为我们将要自定义的控件,使用相对布局置于界面的右侧;

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.itemp.letterindexview.MainActivity"><ListView
        android:id="@+id/lvFriends"android:layout_width="match_parent"android:layout_height="match_parent"/><TextView
        android:id="@+id/tvCurrentLetter"android:layout_width="100dp"android:layout_height="100dp"android:background="@drawable/shape_letterindexview_bg_pressed"android:gravity="center"android:textSize="50sp"android:layout_centerInParent="true"android:textColor="@color/white"android:textStyle="bold"android:visibility="visible"android:text="A" /><com.itemp.letterindexview.LetterIndexView
        android:id="@+id/liv"android:layout_width="35dp"android:layout_height="match_parent"android:layout_margin="5dp"android:layout_alignParentRight="true"/></RelativeLayout>

2、继承于View并使用绘图法在画布上绘制字母:

public class LetterIndexView extends View

3、实现构造方法,在其中初始化画笔,并为控件设置背景图(shape资源制作的圆角矩形)

    public LetterIndexView(Context context) {this(context, null);}public LetterIndexView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public LetterIndexView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//setBackgroundResourece();setBackgroundResource(R.drawable.shape_letterindexview_bg);paint = new Paint();paint.setAntiAlias(true);//抗锯齿}

4、shape资源的定义代码:res/drawable/shape_letterindexview_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="#fff" /><stroke
        android:width="1dp"android:color="#ddd" /><corners android:radius="10dp" />
</shape>

这是一个白色实心的圆角矩形,按下后将其变为黄色实心的圆角矩形,文件为res/drawable/shape_letterindexview_bg_pressed.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="#ff0" /><stroke
        android:width="1dp"android:color="#ddd" /><corners android:radius="10dp" />
</shape>

5、定义字符串数组作为索引的文本:

String[] letters = new 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", "#",
};

6、覆写onDraw()方法,将字母纵向排列均匀地绘制在画布上:

@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (width == 0) {width = getWidth();height = getHeight();}//把字母画在控件上,【选中字母】用红色画笔,否则黑色for (int i = 0; i < letters.length; i++) {//计算startX,控件宽度的一半减去字母宽度的一半String letter = letters[i];float letterSize = paint.measureText(letter);float startX = (width - letterSize) / 2;//startY,上方所有单元格的高度之和+(单元格高度的一半+字母高度的一半)float unitHeight = (height - 40) / 27f;float startY = 20 + i * unitHeight + (unitHeight + letterSize) / 2;//高亮字母为红色,否则为黑色if(i == currentPosition){paint.setColor(Color.RED);}else {paint.setColor(Color.BLACK);}paint.setTextSize(35);paint.setStyle(Paint.Style.FILL_AND_STROKE);//使用加粗效果canvas.drawText(letter, startX, startY, paint);//绘制字母}}

7、接下来覆写onTouchEvent()定义手指在控件上的滑动响应,逻辑为:
·手指按下,整个控件的背景色变为黄色,并根据手指按下的y的位置,确认哪个字母为选中字母,并重绘以将该字母高亮显示,并通知外界响应按下事件(比如显示小窗口见本文末尾GIF)
·手指滑动,动态改变选中字母,并重绘以将该字母高亮显示
·手指抬起,控件背景恢复为默认的白色,并通知外界响应(比如隐藏小窗口见文章末尾GIF)

    @Overridepublic boolean onTouchEvent(MotionEvent event) {float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN://改变背景效果setBackgroundResource(R.drawable.shape_letterindexview_bg_pressed);//根据手指位置设置高亮字母并重绘invalidateCurrentPosition(y);//通知外界手指按下if (callback != null) {callback.onFingerDown(true);}break;case MotionEvent.ACTION_MOVE://根据手指位置设置高亮字母并重绘invalidateCurrentPosition(y);//通知外界字母变化if (callback != null) {callback.onLetterChanged(letters[currentPosition]);}break;case MotionEvent.ACTION_UP://恢复背景效果setBackgroundResource(R.drawable.shape_letterindexview_bg);//通知外界手指抬起if (callback != null) {callback.onFingerDown(false);}break;}return true;}/*** 根据手指位置动态设置高亮字母并重绘* @param y*/private void invalidateCurrentPosition(float y) {currentPosition = (int) ((y / height) * letters.length);if(currentPosition > 26){currentPosition = 26;}invalidate();}

11、以接口的方式通知外界:手指按下或抬起,高亮字母发生改变:

    LetterIndexCallback callback;public void setCallback(LetterIndexCallback callback) {this.callback = callback;}public interface LetterIndexCallback {void onFingerDown(boolean down);void onLetterChanged(String letter);}

12、最后当外界ListView主动滚动时,字母索引的选中字母也随之变化,我们为外界提供公共方法,用于更新选中字母的位置:

    /*** 供外界ListView滚动时通知到当前控件* @param firstLetter*/public void setCurrentLetter(String firstLetter) {for (int i = 0; i < letters.length; i++) {if(letters[i].equals(firstLetter)){setCurrentPosition(i);return;}}}

13、Activity实现【索引控件】的回调接口,并将自身设置给【索引控件】:

public class MainActivity extends AppCompatActivity implements LetterIndexView.LetterIndexCallback 
@Overridepublic void onLetterChanged(String letter) {tvCurrentLetter.setText(letter);}@Overridepublic void onFingerDown(boolean fingerDown) {if(fingerDown){tvCurrentLetter.setVisibility(View.VISIBLE);}else {tvCurrentLetter.setVisibility(View.GONE);}}
letterIndexView.setCallback(this);

效果如下:
这里写图片描述

这篇关于自定义通讯录字母索引的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006192

相关文章

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

Java实现Elasticsearch查询当前索引全部数据的完整代码

《Java实现Elasticsearch查询当前索引全部数据的完整代码》:本文主要介绍如何在Java中实现查询Elasticsearch索引中指定条件下的全部数据,通过设置滚动查询参数(scrol... 目录需求背景通常情况Java 实现查询 Elasticsearch 全部数据写在最后需求背景通常情况下

Pandas中多重索引技巧的实现

《Pandas中多重索引技巧的实现》Pandas中的多重索引功能强大,适用于处理多维数据,本文就来介绍一下多重索引技巧,具有一定的参考价值,感兴趣的可以了解一下... 目录1.多重索引概述2.多重索引的基本操作2.1 选择和切片多重索引2.2 交换层级与重设索引3.多重索引的高级操作3.1 多重索引的分组聚

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

Python中列表的高级索引技巧分享

《Python中列表的高级索引技巧分享》列表是Python中最常用的数据结构之一,它允许你存储多个元素,并且可以通过索引来访问这些元素,本文将带你深入了解Python列表的高级索引技巧,希望对... 目录1.基本索引2.切片3.负数索引切片4.步长5.多维列表6.列表解析7.切片赋值8.删除元素9.反转列表

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

MySQL的索引失效的原因实例及解决方案

《MySQL的索引失效的原因实例及解决方案》这篇文章主要讨论了MySQL索引失效的常见原因及其解决方案,它涵盖了数据类型不匹配、隐式转换、函数或表达式、范围查询、LIKE查询、OR条件、全表扫描、索引... 目录1. 数据类型不匹配2. 隐式转换3. 函数或表达式4. 范围查询之后的列5. like 查询6

PostgreSQL如何查询表结构和索引信息

《PostgreSQL如何查询表结构和索引信息》文章介绍了在PostgreSQL中查询表结构和索引信息的几种方法,包括使用`d`元命令、系统数据字典查询以及使用可视化工具DBeaver... 目录前言使用\d元命令查看表字段信息和索引信息通过系统数据字典查询表结构通过系统数据字典查询索引信息查询所有的表名可

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06