zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    LD_PRELOAD的偷梁换柱之能
    ATOM & Sublime Text 下MarkDown插件功能比较
    存在
    2017年执行计划
    2015年总结以及2016年计划
    2014年总结以及2015年计划
    asp.net MVC中form提交和控制器接受form提交过来的数据
    2013年回顾及2014年计划
    c# XML序列化与反序列化
    Namenode HA原理详解(脑裂)
  • 原文地址:https://www.cnblogs.com/xwgblog/p/3991126.html
Copyright © 2011-2022 走看看