android字母索引实现ListView定位

最近闲的很,没什么事干 ,在玩手机的时间看到android系统自带的那个通讯录软件对联系人的快速定位功能.  感觉这个功能也比较实用自己就试着自己去实现.

虽然网络上还是有大牛封闭好了的框架,但是如果自己来实现一下也是不错的, 个人比较喜欢自己写的东西,别人写好的东西可以拿来借鉴,还是不推荐看也不看直接拿

来用,代码可以复制,作者的思想就需要慢慢体会的.

基本介绍:

   首先安卓本身已经提供一个接口来实现快速定位的, SectionIndexer接口共有三个方法.

   

    Object[] getSections();              //返回所有的section

    

    int getPositionForSection(int sectionIndex);    //根据section索引返回一个position

   int getSectionForPosition(int position);      //与上面的方法正好相反 .

   section可以理解为一个ListView中的一部分,比如在联系人进行分组将首字母相同的分为同一组,每一组就是一个section.

基本设计:

  我将那些字母的列表看成是一个View这个View里面包含一个实现SectionIndexer接口的成员. 且定义一个回调接口用于在索引更改时通知更新ListView.

  重写onMeasure(int,int)方法计算View的宽高.

  

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

			if(mSectionIndex == null){
				super.onMeasure(widthMeasureSpec, heightMeasureSpec);
				return ;
			}

			if(mSections == null)
					mSections =  mSectionIndex.getSections();

			int  	measureHeight ;
			int 		measureWidth ;
			int 		height  =  (int) (sectionHeight() *  mSections.length ) + ( getPaddingTop() + getPaddingBottom() );
			int 		width = 		sectionWidth() + getPaddingLeft() + getPaddingRight();

			/**
			 * 根据布局参数来设置View的宽高.
			 * 如果布局参数的高或宽为LayoutParams.WRAP_CONTENT
			 * 则View的宽高分别为 width , height
			 * 否则直接根据布局参数的数值来设置
			 */
			LayoutParams		lp  = getLayoutParams();
			if(lp.height != LayoutParams.WRAP_CONTENT)
							  height = lp.height;

			if(lp.width  != LayoutParams.WRAP_CONTENT)
					width = lp.width;

			/**     */
			measureHeight = ViewGroup.getChildMeasureSpec(heightMeasureSpec, 0,height);
			measureWidth = ViewGroup.getChildMeasureSpec(widthMeasureSpec, 0, width);

			setMeasuredDimension(measureWidth, measureHeight);
	}

重写onLayout方法,重写该方法的原因是使所有的索引填满View. 不一定要重写onLayout方法,只要在View能够得到高度后再计算就可以.

@Override
protected void onLayout(boolean changed, int left, int top, int right,
		int bottom) {
	 		/**
	 		 * 	view 的高度大于列表显示的高度, 在每一个字母之间加入一些间隔,
	 		 * 		使每一个字母对齐,并填满整个view.
	 		 */
	  int 	viewHeight = getHeight() -  (getPaddingTop() + getPaddingBottom());
	  int   originalHeight = mHeight * mSections.length;

	  int 	overHeight = viewHeight - originalHeight;

	  if(overHeight <= 0) return ;

	  mAlphaInterval = overHeight / (mSections.length);
}

重写onDraw方法,这个方法就不用多说了吧,大家都知道是干什么的,直接上代码.

	@Override
	protected void onDraw(Canvas canvas) {

					if(mSectionIndex == null)
						return ;

					int height = getHeight();
					int widht = getWidth();
						//画背景
					if(mBackground){
						RectF		round = new RectF(0, 0, widht, height);
						canvas.drawRect(round,  mBackgroundPaint);
					}

					//画字母
				 float 		textheight  = mAlphaPaint.descent()- mAlphaPaint.ascent();
				 float  y =  textheight / 1.5f +  getPaddingTop();			//第一个字母偏移 .
				 float  x =  getPaddingLeft() ;
					for(int i = 0; i < mSections.length ; i++){

								if(mCurrentSection == i)
											mAlphaPaint.setColor(Color.BLUE);
								else
											mAlphaPaint.setColor(Color.WHITE);

							 y += mAlphaPadding + mAlphaInterval;
								canvas.drawText(mSections[i].toString()  , x, y,  mAlphaPaint);
								y += mAlphaPadding + textheight  ;
					}

	}

效果图:

  

最后还包含一些辅助方法,就不一一例举的大家下载源码一看便知.

源码下载 :

  http://pan.baidu.com/s/1gdw1gyf

时间: 2024-08-19 06:02:54

android字母索引实现ListView定位的相关文章

android之ListView分组及字母索引导航(2)重构-接口

上篇文章对listView 分组和字母索引导航的实现思路做了分析,并依照思路一步步实现,到最后已经较好的实现了全部功能.但是仔细研究就会发现其实现不够好,主要问题: 1.               对于一个使用范围比较广泛的布局,以上实现不够通用,尤其是Bo中需加上一些多余的字段,这些字字段本身并没有意义. 2.               代码都糅合在activity中. 针对以上两点做一些代码重构.首先我们把其优化为一个通用的activity.这样做成通用的View就很容易:然后对代码进行

浅谈android中手机联系人字母索引表的实现

实际上字母索引表的效果,可以说在现在的众多APP中使用的非常流行,比如支付宝,微信中的联系人,还有购物,买票的APP中选择全国城市,切换城市的时候,这时候的城市也就是按照一个字母索引的顺序来显示,看起来是很方便的.其实这种字母索引表的效果最开始是出现在微信的联系人中.因为觉得这种效果功能在今后的项目中可以说是非常常见,可能会用的上,所以准备来波博客讲述一下实现的原理,一来方便以后自己复习,二来如果能够帮助一些android路上奋斗小伙伴也是蛮有意义的. 下面我们先来看下效果图, 看完效果图后我们

ListView实现字母索引

参考网址:http://blog.csdn.net/appte/article/details/10306341 非常感谢~~! ListView A~Z快速索引这种效果在通信录和城市列表中经常看到,方便用户查找,是一种增加用户体验的好方法. 实现效果: 实现步骤: 1.自定义一个名叫SlideBar 的View. 2.在布局文件中加入这个自定义的View. 3. 在Activity中处理监听事件. 话不多说,上代码 自定义View:SlideBar.java import android.co

玩转android自定义控件二——自定义索引栏listview

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

老猪带你玩转android自定义控件二——自定义索引栏listview

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

Android 自定义 View 实现通讯录字母索引(仿微信通讯录)

一.效果:我们看到很多软件的通讯录在右侧都有一个字母索引功能,像微信,小米通讯录,QQ,还有美团选择地区等等.这里我截了一张美团选择城市的图片来看看: 我们今天就来实现图片中右侧模块的索引功能,包括触摸显示以选中的索引字母.这里我的UI界面主要是参照微信的界面来实现,所以各位也可以对照微信来看看效果,什么都不说了,只有效果图最具有说服力! 二.分析: 我们看到这样的效果我们心理都回去琢磨,他是如何实现的: 首先,它肯定是通过自定义 View 来实现的,因为 Android 没有提供类似这样的控件

android ListView定位

如果一个ListView太长,有时我们希望ListView在从其他界面返回的时候能够恢复上次查看的位置,这就涉及到ListView的定位问题: smoothScrollToPosition需要2.2以上,smoothScrollByOffset需要3.0以上.smoothScrollToPosition可以实现平滑滚动 解决的办法如下: // 保存当前第一个可见的item的索引和偏移量 int index = mList.getFirstVisiblePosition(); View v = m

android之listView定位到指定行同时隐藏输入键盘

帮别人该bug遇到的一个问题,记录下来. listView.setSelection(a); 这个方法可以让让你的listview定位到指定行 但是如果紧接着执行隐藏输入键盘的代码,则会有bug,这个时候定位无法实现. imm.hideSoftInputFromWindow(PatientAddActivity.this .getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 使用切换这个方法隐藏输入法键

8.快速索引、listview

实现这样的效果 布局: <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