標籤:
帶索引欄的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