实现ListView A~Z快速索引

【自定义控件】一、字母索引控件,仿小米联系人字母列表 字母索引控件,仿小米联系人字母列表,控件代码超级简单,很适合学习,为二次开发提供思路。 阅读详情

ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法。

实现步骤:

   1.自定义一个名叫SlideBar 的View。

   2.在布局文件中加入这个自定义的View。

   3. 在Activity中处理监听事件。

接下来讲讲我是怎样实现的:

先来看SlideBar这个类:

package com.folyd.tuan.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 自定义的View,实现ListView A~Z快速索引效果
 * 
 * @author Folyd
 * 
 */
public class SlideBar extends View {
	private Paint paint = new Paint();
	private OnTouchLetterChangeListenner listenner;
	// 是否画出背景
	private boolean showBg = false;
	// 选中的项
	private int choose = -1;
	// 准备好的A~Z的字母数组
	public static String[] letters = { "#", "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" };

	// 构造方法
	public SlideBar(Context context) {
		super(context);
	}

	public SlideBar(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 获取宽和高
		int width = getWidth();
		int height = getHeight() - 30;
		// 每个字母的高度
		int singleHeight = height / letters.length;
		if (showBg) {
			// 画出背景
			canvas.drawColor(Color.parseColor("#55000000"));
		}
		// 画字母
		for (int i = 0; i < letters.length; i++) {
			paint.setColor(Color.BLACK);
			// 设置字体格式
			paint.setTypeface(Typeface.DEFAULT_BOLD);
			paint.setAntiAlias(true);
			paint.setTextSize(20f);
			// 如果这一项被选中,则换一种颜色画
			if (i == choose) {
				paint.setColor(Color.parseColor("#F88701"));
				paint.setFakeBoldText(true);
			}
			// 要画的字母的x,y坐标
			float posX = width / 2 - paint.measureText(letters[i]) / 2;
			float posY = i * singleHeight + singleHeight;
			// 画出字母
			canvas.drawText(letters[i], posX, posY, paint);
			// 重新设置画笔
			paint.reset();
		}
	}

	/**
	 * 处理SlideBar的状态
	 */
	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		final float y = event.getY();
		// 算出点击的字母的索引
		final int index = (int) (y / getHeight() * letters.length);
		// 保存上次点击的字母的索引到oldChoose
		final int oldChoose = choose;
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			showBg = true;
			if (oldChoose != index && listenner != null && index > 0
					&& index < letters.length) {
				choose = index;
				listenner.onTouchLetterChange(event, letters[index]);
				invalidate();
			}
			break;

		case MotionEvent.ACTION_MOVE:
			if (oldChoose != index && listenner != null && index > 0
					&& index < letters.length) {
				choose = index;
				listenner.onTouchLetterChange(event, letters[index]);
				invalidate();
			}
			break;
		case MotionEvent.ACTION_UP:
		default:
			showBg = false;
			choose = -1;
			if (listenner != null && index > 0 && index < letters.length)
				listenner.onTouchLetterChange(event, letters[index]);
			invalidate();
			break;
		}
		return true;
	}

	/**
	 * 回调方法,注册监听器
	 * 
	 * @param listenner
	 */
	public void setOnTouchLetterChangeListenner(
			OnTouchLetterChangeListenner listenner) {
		this.listenner = listenner;
	}

	/**
	 * SlideBar 的监听器接口
	 * 
	 * @author Folyd
	 * 
	 */
	public interface OnTouchLetterChangeListenner {

		void onTouchLetterChange(MotionEvent event, String s);
	}

}

然后在布局文件中加入这个自定义的控件:

   
    <!-- 上面的代码省略掉了-->
    
    
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:divider="@drawable/line3" />

        <TextView
            android:id="@+id/float_letter"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center"
            android:background="#F88701"
            android:gravity="center"
            android:textSize="40sp"
            android:visibility="gone" />

        <com.folyd.tuan.view.SlideBar
            android:id="@+id/slideBar"
            android:layout_width="30dp"
            android:layout_height="wrap_content"
            android:layout_gravity="right|bottom" />
    </FrameLayout>

然后在Activity中注册监听事件:

mSlideBar
				.setOnTouchLetterChangeListenner(new OnTouchLetterChangeListenner() {

					@Override
					public void onTouchLetterChange(MotionEvent event, String s) {

						float_letter.setText(s);
						switch (event.getAction()) {
						case MotionEvent.ACTION_DOWN:
						case MotionEvent.ACTION_MOVE:
							float_letter.setVisibility(View.VISIBLE);
							break;

						case MotionEvent.ACTION_UP:
						default:
							float_letter.postDelayed(new Runnable() {

								@Override
								public void run() {
									float_letter.setVisibility(View.GONE);
								}
							}, 100);
							break;
						}
                       int position  = array.indexOf(s);//这个array就是传给自定义Adapter的
                       mListView.setSelection(position);//调用ListView的setSelection()方法就可实现了
					}
				});

实现效果如下:


     


不过这样子有一个小小的Bug 。360的某个APP也有这个Bug。偷笑那个APP99%也是用这种方式实现的。

请看图:



有人知道是什么Bug吗?

我的Bug是这样的:如果用户手指滑过A之后一直向上滑到,滑到切换城市的黄色标题栏(或滑过Z之后一直向下到滑划出屏幕),因为在整个FrameLayout内用户一直没有弹起手指,所以不能触发MotionEvent.ACTION_UP 这个状态,中间的TextView不能消失。可是我试了MotionEvent的其他一些状态,甚至在switch语句中后面加个default都没用,暂时不知道怎样解决这个小Bug,有知道的朋友还望多多指教。谢谢。



安卓字母索引列表 索引列表, 常用于通讯录,城市选择,选中右边的字母索引可以直接定位到相应的选项 立即下载

相关推荐

暗黑地牢modfiles.txt文件生成工具

暗黑地牢modfiles.txt文件生成工具引言方法工具源码基本步骤 引言 玩过暗黑地牢mod,并手动修改了mod中文件的话,如果不同步修改modfiles.txt文件,就会引起各种问题,典型的比如马车刷不出mod英雄,商店和boss都不再出现mod饰品,怪物贴图丢失出现黑块等,要解决这个问题,就要修正mod文件夹下的modfiles.txt文件 方法 针对修改量大小,一般有几种方法: 如果修改较少,而且你还记得修改了哪几个文件,找到这几个文件,右键属性,查看大小,要用的是括号里面的字节数,然后打开mod

lttclaw_的专栏 5002

Flutter azlistview城市列表页面

城市列表页面效果 在根目录pubspec.yaml文件中添加依赖 dependencies: azlistview: ^1.1.1 lpinyin: ^2.0.3 import 'package:flutter/material.dart'; import 'city_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key key})

华山论码 2775

Syzkaller实战教程2:运行环境配置+实例运行

本文详细介绍了在linux系统上搭建Syzkaller内核模糊测试环境的完整流程。 1.环境配置:通过VMware创建Ubuntu20.04虚拟机A,配置QEMU/KVM虚拟化环境,安装Go语言工具链和Syzkaller; 2.内核编译:下载Linux内核源码并配置KCOV等调试选项,编译生成带覆盖率支持的bzImage内核镜像; 3.测试环境构建:使用debootstrap创建Debian虚拟机镜像,通过QEMU启动嵌套虚拟机B; 实例测试: 4.演示两种测试场景 - 提供完整上手教程

cuguanren的博客 1375

从零开始Flutter版微信APP--通讯录页之AzListView

从零开始Flutter版微信APP--通讯录页之AzListView

iounce 701

SpringBoot 指标监控——Actuator

1、 访问:localhost:8000/actuator 设置健康监控显示具体情况 metrics http://localhost:8000/actuator/metrics/jvm.gc.live.data.size 定制化health信息 //利用构造器,在注册中心中添加cityService.saveCity.count指标 public CityServiceImpl(MeterRegistry meter...

weixin_44302046的博客 4628

从零开始创建Davinci Configurator配置工程

本文介绍了从零开始搭建达芬奇工程的详细步骤。首先安装Vector的CBD包后,通过DavicCFG.exe新建空白ECU工程。文章提到Postbuild相关概念可参考往期文章《AUTOSAR配置中的PostBuild、Precompile、Linktime》,并预告下期将讲解如何通过导入DBC文件来启用AUTOSAR模块。全文以实操截图为主,步骤清晰简明,适合开发者参考备份。

Xiaowestwind的博客 218

Android自定义字母索引

Android字母索引这个功能还是很常见的,例如:电话联系人,城市选择等一些功能都会用到。轮子已造好直接使用,[Github](https://github.com/lzjin/SideBarView.git)地址。 ####效果图: ![gif.gif](https://upload-images.jianshu.io/upload_images/9249152-8997e2ffc6500...

落雨敏 4913

19、情境理论中的信息结构解析

本文系统解析了情境理论中的信息结构,从信息元(infon)的基本概念出发,深入探讨了关系结构与简单信息结构的构建方法,分析了标准信息结构所满足的一系列公理(如A1-A14),并阐述了角色、同一性、高阶信息、循环现象、参数适当性及信息元部分性等核心性质。通过具体示例和流程图展示了信息结构的构建过程,并对比了不同公理下的结构差异,最后讨论了该理论在与其他领域融合中的发展趋势及面临的挑战。

book8的博客 78

推荐开源项目:AzListView - Flutter的理想之选打造精美城市和联系人列表

在开发移动端应用时,构建高效且易于导航的城市列表或联系人列表是一个常见的需求。这正是[AzListView](https://github.com/flutterchina/azlistview)所擅长解决的问题。这个开源库为Flutter开发者提供了一种优雅的方式,快速构建出带有索引及悬停效果的列表界面,为用户提供出色的交互体验。 ## 项目介绍 AzListView是基于[scrollab

gitblog_00041的博客 797

Openclaw错误排查及解决方案之:Previous run is still shutting down. Please try again in a moment.

Openclaw错误排查及解决方案之:Previous run is still shutting down. Please try again in a moment.

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 232

Pyinstaller打包为可执行文件编码错误的问题

Pyinstaller打包为可执行文件编码错误的问题 写好的python程序在vscode上运行没有任何问题,将程序利用pyinstaller打包后,运行程序发生了错误。 错误代码 UnicodeDecodeError: ‘utf-8' codec can't decode byte 0xce in position 20-21:invalid cotinuation byte 网上找到的解决方案是: 1.在命令行中输入 chcp 65001 2.按正常方式进行封装 pyinstaller

xuefeng_he的博客 1559

android a z 快速定位,实现ListView A~Z快速索引

ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法。实现步骤:1.自定义一个名叫SlideBar 的View。2.在布局文件中加入这个自定义的View。3. 在Activity中处理监听事件。接下来讲讲我是怎样实现的:先来看SlideBar这个类:package com.folyd.tuan.view;import android.con...

weixin_39818264的博客 371

11、iOS设备逻辑数据分析全解析

本文深入解析iOS设备中的逻辑数据,涵盖图像相关数据库(Photos.sqlite和PhotosAux.sqlite)、录音文件、iPhoto照片存储结构、多媒体文件、第三方应用程序、社交网络应用(如Twitter、Skype、Facebook等)以及苹果相关应用(如Google Mobile、Bing)的数据存储结构和取证方法。此外,还介绍了文档类应用(如Pages、Numbers、Documents To Go)的文件存储结构及恢复方法。适用于iOS取证、数据挖掘和数字调查领域。

rain6的博客 226

ListView A~Z快速索引--提供源码

ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法。 使用的知识点: 1,汉字转拼音,使用pinyin4j-2.5.0.jar 2,定义类实现Comparable接口,方便排序 3,自定义控件QuickIndexBar继承view(重点) 4,使用接口回调,暴露给外部使用 实现步骤: 1,设置布局 2,使用pinyin4j

wk843620202的专栏 1148

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Android-联系人A~Z列表

Android-联系人A~Z列表实现旅途将右侧A~Z显示出来 自定义一个A~Z垂直显示的View(自定义控件命名为:LetterView.java)/** * 靠右的字母控件 */ public class LetterView extends View { /**纵向显示的所有字符*/ public static final String letters = "*ABCDEFGHIJKLMNOPQ

空白的博客 1125

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Android ListView相关技术

实现ListView A~Z快速索引 http://blog.youkuaiyun.com/appte/article/details/10306341

Hongcenyo_0403_mm的博客 527

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Android ListView A~Z快速索引(改进版)

上一篇文章虽然实现了ListView 快速索引的效果,但是有一个小小的Bug。这个Bug我在前面也说了,这篇文章就来解决这个Bug。 我研究的时候发现只要showBg值为true,中间的字母就显示,而当showBg 的值为false的时候中间的字母就可以消失。只要SlideBar的状态为ACTION_DOWN和ACTION_MOVE 的时候showBg的值为true,而ACTION_UP

对酒当歌 5473

Android ListView A~Z快速索引

上一篇文章虽然实现了ListView 快速索引的效果,但是有一个小小的Bug。这个Bug我在前面也说了,这篇文章就来解决这个Bug。 我研究的时候发现只要showBg值为true,中间的字母就显示,而当showBg 的值为false的时候中间的字母就可以消失。只要SlideBar的状态为ACTION_DOWN和ACTION_MOVE 的时候showBg的值为true,而ACTIO

Max一直在学习 771

android a z 快速定位,Android ListView A~Z快速索引(改进版)

上一篇文章虽然实现了ListView 快速索引的效果,但是有一个小小的Bug。这个Bug我在前面也说了,这篇文章就来解决这个Bug。我研究的时候发现只要showBg值为true,中间的字母就显示,而当showBg 的值为false的时候中间的字母就可以消失。只要SlideBar的状态为ACTION_DOWN和ACTION_MOVE 的时候showBg的值为true,而ACTION_UP的时候sho...

weixin_35931397的博客 212
上一篇: Android ListView 图片异步加载和图片内存缓存
下一篇: Android ListView A~Z快速索引(改进版)
何必纠结于ID
博客等级 码龄14年 65粉丝 64原创
评论 16
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值