玩转android自定义控件二——自定义索引栏listview
带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样:
今天,我们就从零到一实现这个具有索引栏的listview.
怎么实现这个控件了,我们应当梳理出一个思路。
①首先应当将字母的索引栏继承与一个控件,通过ondraw方法将字母画出来。
②然后我们应该监听这个字母控件的ontouch事件,来判断用户到底是按了那个字母。
③就是实现这个索引栏与listview的联动,就是将listview滑动到按下字母的位置。
大体流程图如下:
有了前面铺垫,我们引出本文重头戏——代码。
首先,索引栏这个控件如何将字母绘制在控件上的代码:

/**
* 侧边栏显示字母
*/
private String[] words = { "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", "#" };
/**
* 绘制列表控件的方法
* 将要绘制的字母以从上到下的顺序绘制在一个指定区域
* 如果是进行选中的字母就进行高亮显示
*/
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
int height = getHeight();// 获取对应高度
int width = getWidth(); // 获取对应宽度
int singleHeight = height / words.length;// 获取每一个字母的高度 for (int i = 0; i < words.length; i++) {
paint.setColor(Color.rgb(33, 65, 98));
// paint.setColor(Color.WHITE);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
paint.setTextSize(20f);
// 选中的状态
if (isdown) {
paint.setColor(Color.parseColor("#ffffff"));
//paint.setFakeBoldText(true);
}
// x坐标等于中间-字符串宽度的一半.
float xPos = width / 2 - paint.measureText(words[i]) / 2;
float yPos = singleHeight * i + singleHeight;
canvas.drawText(words[i], xPos, yPos, paint);
paint.reset();// 重置画笔
}
}

通过上述的代码,我们可以得出以下的结论:将要绘制的字母以从上到下的顺序绘制在一个指定区域,每个字母的x坐标是一样的,x坐标即为控件宽度一半。如果当前字母选中的话,就高亮显示。思路如图所示:
紧接着,就来到第二步,确定用户到底点击是那个字母,代码如下:

/**
* 处理触摸事件的方法
* 用户按下时候,整个控件背景变化
* 根据按下y坐标 判断究竟用户按下那个字母
* 当前字母高亮显示 将其字母显示listview中央
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int action = event.getAction();
final float y = event.getY();// 点击y坐标
final int oldChoose = choose;
final ITouchingLetterChangedListener listener = onTouchingLetterChangedListener;
final int c = (int) (y / getHeight() * words.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
switch (action) {
case MotionEvent.ACTION_UP:
isdown=false;
setBackgroundResource(android.R.color.transparent);
choose = -1;//
invalidate();
if (textViewDialog != null) {
textViewDialog.setVisibility(View.INVISIBLE);
}
break; default:
isdown=true;
setBackgroundResource(R.color.sidebar_bg_color);
if (oldChoose != c) {
if (c >= 0 && c < words.length) {
if (listener != null) {
listener.OnTouchingLetterChanged(words[c]);
}
if (textViewDialog != null) {
textViewDialog.setText(words[c]);
textViewDialog.setVisibility(View.VISIBLE);
} choose = c;
invalidate();
}
}
break;
}
return true;
}

通过上述的代码,我们可以这样总结:当用户按下的时候,整个控件背景发生变化,根据用户按下的y坐标来确定用户究竟是按下那个字母,并且将按下字母显示屏幕的中央,效果图如下:
最终,将listview 移动到按下字母相应位置,代码如下:

/**
* 根据用户点击那个字母将listview移动到相应位置
*/
sidebar.setOnTouchingLetterChangedListener(new ITouchingLetterChangedListener() { @Override
public void OnTouchingLetterChanged(String cString) {
int position = -1;
if (cString.length() > 0) {
position = myAdapter.getPositionForSection(cString
.charAt(0));
}
if (position != -1) {
listview.setSelection(position);
} else if (cString.contains("#")) {
listview.setSelection(0);
}
}
});

连篇累牍说了这么多,控件大功告成的效果为:
源代码地址为:
http://pan.baidu.com/s/1dDMDjhR
玩转android自定义控件二——自定义索引栏listview的更多相关文章
- 老猪带你玩转android自定义控件二——自定义索引栏listview
带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...
- Android自定义控件之自定义ViewGroup实现标签云
前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...
- Android自定义控件之自定义组合控件
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
- Android自定义控件之自定义组合控件(三)
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
- 老猪带你玩转android自定义控件一——打造最简单viewpagerindicator
viewpagerindicator,既使用viewpager翻页时候,标题的指示条随着改变的控件,是常用android控件之一,几乎所有的新闻类APP中都有使用.如下图所示: 今天,我们将从0到1实 ...
- android自定义控件(4)-自定义水波纹效果
一.实现单击出现水波纹单圈效果: 照例来说,还是一个自定义控件,观察这个效果,发现应该需要重写onTouchEvent和onDraw方法,通过在onTouchEvent中获取触摸的坐标,然后以这个坐标 ...
- android自定义控件(3)-自定义当前按钮属性
那么还是针对我们之前写的自定义控件:开关按钮为例来说,在之前的基础上,我们来看看有哪些属性是可以自定义的:按钮的背景图片,按钮的滑块图片,和按钮的状态(是开还是关),实际上都应该是可以在xml文件中直 ...
- android 自定义控件二之仿QQ长按删除
自定义Dialog 1.先上个效果图:
- android自定义控件(五) 自定义组合控件
转自http://www.cnblogs.com/hdjjun/archive/2011/10/12/2209467.html 代码为自己编写 目标:实现textview和ImageButton组合, ...
随机推荐
- hdu 5918(强行水过去..正解KMP)
Sequence I Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- css3 图标变大变小在变小变大
css3 @-webkit-keyframes anLoca { from { -webkit-transform: scale3d(1, 1, 1); } to { -webkit-transfor ...
- vue框架muse-ui官网文档主题错误毕竟【01】
在使用了element-ui后,总觉得不尽兴,再学一个响应式的muse-ui发现是个小众框架,但是我很喜欢. 指出官网文档里的主题使用描述错误. 首先,在vue-cli里安装raw-loader:np ...
- CentOS7.6打开的程序窗口居中
每次在CentOS7中打开新的窗口都会靠左上角显示,所以每次打开一个窗口都要多做一步操作,将窗口移到屏幕中间来,强迫症的我觉得太麻烦了,所以… 安装ccsm yum -y install compi ...
- spring_150807_hibernate_transaction_annotation
实体类: package com.spring.model; import javax.persistence.Entity; import javax.persistence.Id; import ...
- jquery选择器详细说明
jquery中选择器感觉是用的特别多并且特别方便的一个方法,今天就在这里详细的记载下大多数常用的选择器,一起学习探讨. 首先介绍的是css3的选择器,其中包括了标签选择器(div),ID选择器(#ID ...
- XV6操作系统代码阅读心得(二):进程
1. 进程的基本概念 从抽象的意义来说,进程是指一个正在运行的程序的实例,而线程是一个CPU指令执行流的最小单位.进程是操作系统资源分配的最小单位,线程是操作系统中调度的最小单位.从实现的角度上讲,X ...
- Eclipse项目红色叹号解决方法
情况:就是项目出现红色感叹号 解决方法: 对准项目右键选择Build Path → configure build path 点击eclipse项目的configure build path后,在弹出 ...
- JAVAEE学习——hibernate02:实体规则、对象状态、缓存、事务、批量查询和实现客户列表显示
一.hibernate中的实体规则 实体类创建的注意事项 1.持久化类提供无参数构造 2.成员变量私有,提供共有get/set方法访问.需提供属性 3.持久化类中的属性,应尽量使用包装类型 4.持久化 ...
- logging记录日志
日志是一个系统的重要组成部分,用以记录用户操作.系统运行状态和错误信息.日志记录的好坏直接关系到系统出现问题时定位的速度.logging模块Python2.3版本开始成为Python标准库的一部分. ...