標籤:des android style blog http color io os java
最近閑的很,沒什麼事幹 ,在玩手機的時間看到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的寬高.
@Overrideprotected 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 * 否則直接根據布局參數的數值來設定 */LayoutParamslp = 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能夠得到高度後再計算就可以.
@Overrideprotected 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方法,這個方法就不用多說了吧,大家都知道是幹什麼的,直接上代碼.
@Overrideprotected void onDraw(Canvas canvas) {if(mSectionIndex == null)return ;int height = getHeight();int widht = getWidth();//畫背景if(mBackground){RectFround = 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);elsemAlphaPaint.setColor(Color.WHITE); y += mAlphaPadding + mAlphaInterval;canvas.drawText(mSections[i].toString() , x, y, mAlphaPaint);y += mAlphaPadding + textheight ;}}
:
最後還包含一些輔助方法,就不一一例舉的大家下載源碼一看便知.
源碼下載 :
http://pan.baidu.com/s/1gdw1gyf
android字母索引實現ListView定位