效果图:

布局去指定

view.custom.shangguigucustomview.MyCustomIndexView 自定义View对象
<!-- 自定义联系人快速索引 -->
<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"
android:orientation="vertical"
tools:context=".ShangGuiguTestActivity"> <ListView
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView> <TextView
android:id="@+id/tv_word"
android:layout_width="80dp"
android:layout_height="80dp"
android:background="#22000000"
android:layout_centerInParent="true"
android:textSize="40dp"
android:textColor="@android:color/black"
android:gravity="center_horizontal|center_vertical"
android:visibility="gone"
/> <view.custom.shangguigucustomview.MyCustomIndexView
android:id="@+id/mycustom_indexview"
android:layout_width="30dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:background="#f00000"
/> </RelativeLayout>

自定义联系人快速索引处理类:

public class MyCustomIndexView extends View { // 为什么是继承View,因为不需要操纵孩子,只需要操纵TextView

    private static final String TAG = MyCustomIndexView.class.getSimpleName();

    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"}; private IMyCustomIndexBack iBack2; public void setBack(IMyCustomIndexBack iBack2) {
this.iBack2 = iBack2;
} private Paint paint; public MyCustomIndexView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs); paint = new Paint();
paint.setTextSize(40);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setColor(Color.WHITE);
} private int indexViewWidth;
private int itemIndexViewHeight; private int heightMeasureSpec; private int itemHeight; @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); itemIndexViewHeight = heightMeasureSpec / words.length;
indexViewWidth = widthMeasureSpec; this.heightMeasureSpec = heightMeasureSpec; // setMeasuredDimension(indexViewWidth, indexViewHeight); // itemHeight = getMeasuredHeight() / words.length;
itemHeight = MeasureSpec.getSize(heightMeasureSpec) / words.length; Log.i(TAG, "高度实验: getMeasuredHeight():"+getMeasuredHeight() + " heightMeasureSpec:" + heightMeasureSpec);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); int w = MeasureSpec.getSize(indexViewWidth);
int h = MeasureSpec.getSize(itemIndexViewHeight);
int defaultH = MeasureSpec.getSize(heightMeasureSpec); int defaultH26 = defaultH / words.length; for (int i=0; i<words.length;i++) {
if (wordIndexValue==i) {
paint.setColor(Color.BLACK);
paint.setTextSize(50);
} else {
paint.setColor(Color.WHITE);
paint.setTextSize(40);
} String word = words[i]; // 我要得到字体到宽度
Rect rect = new Rect();
// 需要用到画笔 把值处理好传递给Rect
paint.getTextBounds(word, 0, 1, rect); canvas.drawText(word, (w/2) - rect.width()/2, i==0?defaultH26:defaultH26*(i+1), paint);
} } private int wordIndexValue = -1; private int tempWordIndexValue; @Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
/*float endY = event.getY();
Log.i(TAG, "endy:" + endY);
// 得到字母索引
int abcIndex = (int) (endY / itemIndexViewHeight);
Log.i(TAG, "abcIndex:" + abcIndex);*/ float Y = event.getY();
wordIndexValue = (int) (Y/itemHeight);//字母索引
Log.i(TAG, "wordIndexValue;" + wordIndexValue); if (tempWordIndexValue != wordIndexValue) {
iBack2.back(wordIndexValue, words[wordIndexValue]);
}
tempWordIndexValue = wordIndexValue;
invalidate(); break;
case MotionEvent.ACTION_UP:
iBack2.upEnd(); tempWordIndexValue = 0; wordIndexValue = -1;
invalidate();
break;
default:
break;
}
return true;
}
}

如何使用自定义联系人快速索引:

/**
* 自定义联系人快速索引
*/
tv_word = (TextView) findViewById(R.id.tv_word); final MyCustomIndexView myCustomIndexView = findViewById(R.id.mycustom_indexview);
myCustomIndexView.setBack(new IMyCustomIndexBack() {
@Override
public void back(int index, String word) {
tv_word.setVisibility(View.VISIBLE);
tv_word.setText(word);
// Toast.makeText(MainActivity.this, "index:" + index + " word:" + word, Toast.LENGTH_SHORT).show();
} @Override
public void upEnd() {
handler.sendEmptyMessageDelayed(0, 0);
}
});
/**
* 自定义联系人快速索引
*/
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
alphaAnimation.setDuration(3000);
alphaAnimation.setFillAfter(true); tv_word.startAnimation(alphaAnimation);
// tv_word.setVisibility(View.GONE);
}
};

Android-自定义联系人快速索引的更多相关文章

  1. Android 自定义支持快速搜索筛选的选择控件(一)

    Android 自定义支持快速搜索筛选的选择控件 项目中遇到选择控件选项过多,需要快速查找匹配的情况. 做了简单的Demo,效果图如下: 源码地址:https://github.com/whieenz ...

  2. Android 自定义View-字母索引表(一)

    在有些Android应用中,为了方便快速定位,经常会看到屏幕右侧有一个字母索引表,今天尝试使用自定义View的方式实现了索引表的基本布局. 字母索引表的样式如下面的示意图所示, 此时我们至少需要知道以 ...

  3. Android自定义模糊匹配搜索控件(二)

    在项目中遇到一个需要通过某个字的值筛选匹配带出其他信息的需求,在这里将实现思路整理出来. 源码地址:https://github.com/whieenz/SearchSelect 先看效果图 上图中的 ...

  4. Android 快速索引(城市列表和联系人)

    最近需要实现一个城市列表的快速索引功能.类似于联系人应用,根据姓名首字母快速索引功能. 要实现这个功能只需要解决两个问题:1.对列表进行分组(具有同一特征),并且能够快速定位到该组的第一项 2.右侧分 ...

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

    上一篇文章虽然实现了ListView 快速索引的效果,但是有一个小小的Bug.这个Bug我在前面也说了,这篇文章就来解决这个Bug. 我研究的时候发现只要showBg值为true,中间的字母就显示,而 ...

  6. 快速索引 (对View的自定义)

    快速索引 (对View的自定义) 快速索引应用场景: 微信好友列表, 联系人通讯录, 应用管理, 文件管理等. 快速索引7步曲: *1. A-Z索引的绘制. * 2. 处理Touch事件. * 3. ...

  7. Android系统联系人全特效实现(下),字母表快速滚动

    在上一篇文章中,我和大家一起实现了类似于Android系统联系人的分组导航和挤压动画功能,不过既然文章名叫做<Android系统联系人全特效实现>,那么没有快速滚动功能显然是称不上&quo ...

  8. android系统联系人分组特效实现(2)---字母表快速滚动

    要实现这种功能,只需要在   android系统联系人分组特效实现(1)---分组导航和挤压动画  的基础上再加上一个自定义控件即可完成. 1.新建项目,继续新建一个java类,BladeView,用 ...

  9. 【Android】如何快速构建Android Demo

    [Android]如何快速构建Android Demo 简介 在 Android 学习的过程中,经常需要针对某些项目来写一些测试的例子,或者在做一些 demo 的时候,都需要先写 Activity 然 ...

随机推荐

  1. 修改Gradle 和Maven本地仓库的位置方法

    本文转载自:https://www.cnblogs.com/dwb91/p/6523541.html 关于Maven的配置: 用过Maven的开发人员应该知道Maven可以通过配置 conf文件夹下面 ...

  2. F5 SNAT NAT相关

    SNAT: 跟路由器.防火墙一样,BIG-IP系统提供NAT (Network Address Translation)和SNAT(Secure Network Address Translation ...

  3. 2018 Multi-University Training Contest 4-Glad You Came(hdu 6356)

    一.思路 线段树维护一个区间最小值,然后对于每次操作,做区间更新即可.要注意的是,在更新的时候,记得剪枝:如果当前更新的值$v \le minv$(minv为当前线段树节点所管辖区间的最小值),直接返 ...

  4. Oracle 11.2.0.3.0 RAC GI_DB升级到11.2.0.4.0

    转载:  http://blog.csdn.net/frank0521/article/details/18226199 前言 还是大家常说的那句:生产环境千万记得备份哈~~~ 以下的环境,是我的测试 ...

  5. bootstrap的引入和使用

    Bootstrap的下载 一. 使用Bootstrap第一步,先将生成环境的Bootstrap下载下来.然后将下载,然后引入到自己建好的当前目录中 二.点到起步中的基本模板 将看到的整段代码复制粘贴到 ...

  6. linux centos 6.1 安装 redis

    1, yum install redis 检测是否有redis 2,没有的话就运行:yum install epel-release 3,再执行 yum install redis

  7. 学习了django对于sqlite3进行了了解,谈谈看法

    学习了django对于sqlite3进行了了解,谈谈看法 由于django默认使用的是sqlite3,写了几个建表语句, 然后数据做下迁移,其实就是建表语句的执行. 一直对sqlite3没有一个直观的 ...

  8. C#串口编程测试收发

    原文:http://www.cnblogs.com/vsdot/archive/2013/04/23/3263348.html   基本传递方法:RS232传输要有1位起始位,8位数据位.1位校验位( ...

  9. window10上安装python+CUDA+CuDNN+TensorFlow

    软件 版本 Window10 X64 python 3.6.4(64位) CUDA CUDA Toolkit 9.0 (Sept 2017) CuDNN cuDNN v7.0.5 (Dec 5, 20 ...

  10. 如何使用find命令在Linux中查找文件

    Linux Find命令是Linux系统管理员工具库中最强大的工具之一. Find是一个命令行实用程序,它允许您根据用户给定的表达式搜索目录层次结构中的文件和目录,并对每个匹配的文件应用用户指定的操作 ...