老猪带你玩转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自定义控件一——打造最简单viewpagerindicator
viewpagerindicator,既使用viewpager翻页时候,标题的指示条随着改变的控件,是常用android控件之一,几乎所有的新闻类APP中都有使用.如下图所示: 今天,我们将从0到1实 ...
- 老猪带你玩转自定义控件三——sai大神带我实现ios 8 时间滚轮控件
ios 8 的时间滚轮控件实现了扁平化,带来很好用户体验,android没有现成控件,小弟不才,数学与算法知识不过关,顾十分苦恼,幸好在github上找到sai大神实现代码,甚为欣喜,顾把学习这个控件 ...
- 老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩、击穿、穿透
前文回顾 建议前一篇文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 过期策略 Redis 的过期策略都有哪些? 在聊这个问题之前,一定 ...
- 老司机带你玩转面试(3):Redis 高可用之主从模式
前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...
- 老司机带你玩转面试(4):Redis 高可用之哨兵模式
前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...
- 老司机带你玩转面试(5):Redis 集群模式 Redis Cluster
前文回顾 建议前面文章没看过的同学先看下前面的文章: 「老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化」 「老司机带你玩转面试(2):Redis 过期策略以及缓存雪崩.击穿. ...
- Android自定义控件之自定义ViewGroup实现标签云
前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...
- Android自定义控件之自定义组合控件
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
随机推荐
- FireDAC 下的 Sqlite [1] - 前言
很长时间没静下心来写博客了, 现在回来, 是 Delphi 不断地进步让我感动.振奋. Delphi XE5 并入了 FireDAC, 第一印象非常好, 恐怕 dbExpress 等等都要靠边站了. ...
- 使用ptrace向已运行进程中注入.so并执行相关函数(转)
1. 简介 使用ptrace向已运行进程中注入.so并执行相关函数,其中的“注入”二字的真正含义为:此.so被link到已运行进程(以下简称为:目标进程)空间中,从而.so中的函数在目标进程空间中有对 ...
- Virtualenv教程
虚拟环境简介 VirtualEnv用于在一台机器上创建多个独立的Python虚拟运行环境,多个Python环境相互独立,互不影响,它能够: 在没有权限的情况下安装新套件 不同应用可以使用不同的套件版本 ...
- C#实现路由器断开连接,更改公网ip
publicstaticvoid Disconnect() { string url ="断 线"; string uri ="http://192.168.1.1 ...
- Yarn中ResourceManager的RPC协议
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemNjXzAwMTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- jQuery Pagination分页插件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Ioc:The basic pattern for integrating Autofac into your application
The basic pattern for integrating Autofac into your application is: Structure your app with inversio ...
- 无法上外网, ping网关ping不通的解决——arp命令
转自:http://jingyan.baidu.com/article/3c48dd34873909e10be35894.html 转自:http://man.linuxde.net/arp 用来管理 ...
- linux下生成https的crt和key证书
今天在配置kibana权限设置时,kibana要求使用https链接. 于是总结了一下linux下openssl生成 签名的步骤: x509证书一般会用到三类文,key,csr,crt Key 是 ...
- wdcp支持两种安装方式
v3.2版本已发布,支持多PHP版本共存共用,支持SSL证书,更多可看论坛 v3版讨论区 更多安装说明请看 http://www.wdlinux.cn/bbs/thread-57643-1-1.htm ...