基本上很多应用都是用了这个功能当数据多时方便快速查看浏览定位查询等,本案例功能比较简单,需要跟完善的话就要继续优化。
先上运行效果图如下:
?
?
?
第一步:首相自定义SideBar类继承View类,用于绘制A-Z文字控件,如下:
?
- import?android.content.Context; ??
- import?android.graphics.Bitmap; ??
- import?android.graphics.BitmapFactory; ??
- import?android.graphics.Canvas; ??
- import?android.graphics.Paint; ??
- import?android.graphics.Paint.Style; ??
- import?android.graphics.drawable.ColorDrawable; ??
- import?android.util.AttributeSet; ??
- import?android.view.MotionEvent; ??
- import?android.view.View; ??
- import?android.widget.HeaderViewListAdapter; ??
- import?android.widget.ListView; ??
- import?android.widget.SectionIndexer; ??
- import?android.widget.TextView; ??
- ??
- public?class?SideBar?extends?View?{ ??
- ????private?char[]?l; ??
- ????private?SectionIndexer?sectionIndexter?=?null; ??
- ????private?ListView?list; ??
- ????private?TextView?mDialogText; ??
- ????Bitmap?mbitmap; ??
- ????private?int?type?=?1; ??
- ????private?int?color?=?0xff858c94; ??
- ??
- ????public?SideBar(Context?context)?{ ??
- ????????super(context); ??
- ????????init(); ??
- ????} ??
- ??
- ????public?SideBar(Context?context,?AttributeSet?attrs)?{ ??
- ????????super(context,?attrs); ??
- ????????init(); ??
- ????} ??
- ??
- ????private?void?init()?{ ??
- ??
- ????????l?=?new?char[]?{?'!','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','#'}; ??
- ????????mbitmap?=?BitmapFactory.decodeResource(getResources(), ??
- ????????????????R.drawable.scroll_bar_search_icon); ??
- ????} ??
- ??
- ????public?SideBar(Context?context,?AttributeSet?attrs,?int?defStyle)?{ ??
- ????????super(context,?attrs,?defStyle); ??
- ????????init(); ??
- ????} ??
- ??
- ??
- ????public?void?setListView(ListView?_list)?{ ??
- ????????list?=?_list; ??
- ????????HeaderViewListAdapter?ha?=?(HeaderViewListAdapter)?_list ??
- ????????????????.getAdapter(); ??
- ????????MyAdapter?ad?=?(MyAdapter)ha.getWrappedAdapter(); ??
- ????????sectionIndexter?=?(SectionIndexer)?ad; ??
- ???????? ??
- ????} ??
- ??
- ????public?void?setTextView(TextView?mDialogText)?{ ??
- ????????this.mDialogText?=?mDialogText; ??
- ????} ??
- ??
- ????public?boolean?onTouchEvent(MotionEvent?event)?{ ??
- ??
- ????????super.onTouchEvent(event); ??
- ????????int?i?=?(int)?event.getY(); ??
- ??
- ????????int?idx?=?i?/?(getMeasuredHeight()?/?l.length); ??
- ????????if?(idx?>=?l.length)?{ ??
- ????????????idx?=?l.length?-?1; ??
- ????????}?else?if?(idx?<?0)?{ ??
- ????????????idx?=?0; ??
- ????????} ??
- ????????if?(event.getAction()?==?MotionEvent.ACTION_DOWN ??
- ????????????????||?event.getAction()?==?MotionEvent.ACTION_MOVE)?{ ??
- ????????????setBackgroundResource(R.drawable.scrollbar_bg); ??
- ????????????mDialogText.setVisibility(View.VISIBLE); ??
- ????????????if?(idx?==?0)?{ ??
- ????????????????mDialogText.setText("Search"); ??
- ????????????????mDialogText.setTextSize(16); ??
- ????????????}?else?{ ??
- ????????????????mDialogText.setText(String.valueOf(l[idx])); ??
- ????????????????mDialogText.setTextSize(34); ??
- ????????????} ??
- ????????????if?(sectionIndexter?==?null)?{ ??
- ??
- ???????????? ??
- ??
- ????????????????sectionIndexter?=?(SectionIndexer)?list.getAdapter(); ??
- ???????????????? ??
- ????????????} ??
- ????????????int?position?=?sectionIndexter.getPositionForSection(l[idx]); ??
- ??
- ????????????if?(position?==?-1)?{ ??
- ????????????????return?true; ??
- ????????????} ??
- ????????????list.setSelection(position); ??
- ????????}?else?{ ??
- ????????????mDialogText.setVisibility(View.INVISIBLE); ??
- ??
- ????????} ??
- ????????if?(event.getAction()?==?MotionEvent.ACTION_UP)?{ ??
- ????????????setBackgroundDrawable(new?ColorDrawable(0x00000000)); ??
- ????????} ??
- ????????return?true; ??
- ????} ??
- ??
- ????protected?void?onDraw(Canvas?canvas)?{ ??
- ????????Paint?paint?=?new?Paint(); ??
- ????????paint.setColor(color); ??
- ????????paint.setTextSize(12); ??
- ????????paint.setStyle(Style.FILL);????? ??
- ????????paint.setTextAlign(Paint.Align.CENTER); ??
- ????????float?widthCenter?=?getMeasuredWidth()?/?2; ??
- ????????if?(l.length?>?0)?{ ??
- ????????????float?height?=?getMeasuredHeight()?/?l.length; ??
- ????????????for?(int?i?=?0;?i?<?l.length;?i++)?{ ??
- ????????????????if?(i?==?0?&&?type?!=?2)?{ ??
- ????????????????????canvas.drawBitmap(mbitmap,?widthCenter?-?7,?(i?+?1) ??
- ????????????????????????????*?height?-?height?/?2,?paint); ??
- ????????????????}?else??
- ????????????????????canvas.drawText(String.valueOf(l[i]),?widthCenter, ??
- ????????????????????????????(i?+?1)?*?height,?paint); ??
- ????????????} ??
- ????????} ??
- ????????this.invalidate(); ??
- ????????super.onDraw(canvas); ??
- ????} ??
- }??
import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Style;import android.graphics.drawable.ColorDrawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.HeaderViewListAdapter;import android.widget.ListView;import android.widget.SectionIndexer;import android.widget.TextView;public class SideBar extends View { private char[] l; private SectionIndexer sectionIndexter = null; private ListView list; private TextView mDialogText; Bitmap mbitmap; private int type = 1; private int color = 0xff858c94; public SideBar(Context context) { super(context); init(); } public SideBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { l = new char[] { '!','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','#'}; mbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.scroll_bar_search_icon); } public SideBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public void setListView(ListView _list) { list = _list; HeaderViewListAdapter ha = (HeaderViewListAdapter) _list .getAdapter(); MyAdapter ad = (MyAdapter)ha.getWrappedAdapter(); sectionIndexter = (SectionIndexer) ad; } public void setTextView(TextView mDialogText) { this.mDialogText = mDialogText; } public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); int i = (int) event.getY(); int idx = i / (getMeasuredHeight() / l.length); if (idx >= l.length) { idx = l.length - 1; } else if (idx < 0) { idx = 0; } if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) { setBackgroundResource(R.drawable.scrollbar_bg); mDialogText.setVisibility(View.VISIBLE); if (idx == 0) { mDialogText.setText("Search"); mDialogText.setTextSize(16); } else { mDialogText.setText(String.valueOf(l[idx])); mDialogText.setTextSize(34); } if (sectionIndexter == null) { sectionIndexter = (SectionIndexer) list.getAdapter(); } int position = sectionIndexter.getPositionForSection(l[idx]); if (position == -1) { return true; } list.setSelection(position); } else { mDialogText.setVisibility(View.INVISIBLE); } if (event.getAction() == MotionEvent.ACTION_UP) { setBackgroundDrawable(new ColorDrawable(0x00000000)); } return true; } protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(color); paint.setTextSize(12); paint.setStyle(Style.FILL); paint.setTextAlign(Paint.Align.CENTER); float widthCenter = getMeasuredWidth() / 2; if (l.length > 0) { float height = getMeasuredHeight() / l.length; for (int i = 0; i < l.length; i++) { if (i == 0 && type != 2) { canvas.drawBitmap(mbitmap, widthCenter - 7, (i + 1) * height - height / 2, paint); } else canvas.drawText(String.valueOf(l[i]), widthCenter, (i + 1) * height, paint); } } this.invalidate(); super.onDraw(canvas); }}
?
?
第二步:设计xml:
?
- <FrameLayout?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"?>??
- ??
- ????<ListView??
- ????????android:id="@+id/list"??
- ????????android:layout_width="fill_parent"??
- ????????android:layout_height="fill_parent"??
- ????????android:divider="@null"?/>??
- ??
- ????<com.example.listsildedel.SideBar??
- ????????android:id="@+id/sideBar"??
- ????????android:layout_width="25dp"??
- ????????android:layout_height="wrap_content"??
- ????????android:layout_gravity="right|center_vertical"?/>??
- ??
- </FrameLayout>??
<FrameLayout 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" > <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:divider="@null" /> <com.example.listsildedel.SideBar android:id="@+id/sideBar" android:layout_width="25dp" android:layout_height="wrap_content" android:layout_gravity="right|center_vertical" /></FrameLayout>
?
第三步:创建MyAdapter继承BaseAdapter并实现SectionIndexer接口注意这里一定要实现这个接口以便实现对应a-z的选择定位功能:
?
- import?java.util.List; ??
- ??
- import?android.content.Context; ??
- import?android.view.LayoutInflater; ??
- import?android.view.View; ??
- import?android.view.ViewGroup; ??
- import?android.widget.BaseAdapter; ??
- import?android.widget.SectionIndexer; ??
- import?android.widget.TextView; ??
- ??
- public?class?MyAdapter?extends?BaseAdapter?implements?SectionIndexer{ ??
- ??
- ????private?List<Content>?list?=?null; ??
- ????private?Context?mContext; ??
- ????private?SectionIndexer?mIndexer; ??
- ???? ??
- ????public?MyAdapter(Context?mContext,?List<Content>?list)?{ ??
- ????????this.mContext?=?mContext; ??
- ????????this.list?=?list; ??
- ??
- ????} ??
- ??
- ????public?int?getCount()?{ ??
- ????????return?this.list.size(); ??
- ????} ??
- ??
- ????public?Object?getItem(int?position)?{ ??
- ????????return?null; ??
- ????} ??
- ??
- ????public?long?getItemId(int?position)?{ ??
- ????????return?position; ??
- ????} ??
- ??
- ????public?View?getView(final?int?position,?View?view,?ViewGroup?arg2)?{ ??
- ????????ViewHolder?viewHolder?=?null; ??
- ????????if?(view?==?null)?{ ??
- ????????????viewHolder?=?new?ViewHolder(); ??
- ????????????view?=?LayoutInflater.from(mContext).inflate(R.layout.item,?null); ??
- ????????????viewHolder.tvTitle?=?(TextView)?view.findViewById(R.id.title); ??
- ????????????viewHolder.tvLetter?=?(TextView)?view.findViewById(R.id.catalog); ??
- ????????????view.setTag(viewHolder); ??
- ????????}?else?{ ??
- ????????????viewHolder?=?(ViewHolder)?view.getTag(); ??
- ????????} ??
- ????????final?Content?mContent?=?list.get(position); ??
- ????????if?(position?==?0)?{ ??
- ????????????viewHolder.tvLetter.setVisibility(View.VISIBLE); ??
- ????????????viewHolder.tvLetter.setText(mContent.getLetter()); ??
- ????????}?else?{ ??
- ????????????String?lastCatalog?=?list.get(position?-?1).getLetter(); ??
- ????????????if?(mContent.getLetter().equals(lastCatalog))?{ ??
- ????????????????viewHolder.tvLetter.setVisibility(View.GONE); ??
- ????????????}?else?{ ??
- ????????????????viewHolder.tvLetter.setVisibility(View.VISIBLE); ??
- ????????????????viewHolder.tvLetter.setText(mContent.getLetter()); ??
- ????????????} ??
- ????????} ??
- ???? ??
- ????????viewHolder.tvTitle.setText(this.list.get(position).getName()); ??
- ???????? ??
- ????????return?view; ??
- ??
- ????} ??
- ???? ??
- ??
- ??
- ????final?static?class?ViewHolder?{ ??
- ????????TextView?tvTitle; ??
- ????????TextView?tvLetter; ??
- ????} ??
- ??
- ??
- ????public?Object[]?getSections()?{ ??
- ????????//?TODO?Auto-generated?method?stub ??
- ????????return?null; ??
- ????} ??
- ??
- ????public?int?getSectionForPosition(int?position)?{ ??
- ???????? ??
- ????????return?0; ??
- ????} ??
- ??
- ????public?int?getPositionForSection(int?section)?{ ??
- ????????Content?mContent; ??
- ????????String?l; ??
- ????????if?(section?==?'!')?{ ??
- ????????????return?0; ??
- ????????}?else?{ ??
- ????????????for?(int?i?=?0;?i?<?getCount();?i++)?{ ??
- ????????????????mContent?=?(Content)?list.get(i); ??
- ????????????????l?=?mContent.getLetter(); ??
- ????????????????char?firstChar?=?l.toUpperCase().charAt(0); ??
- ????????????????if?(firstChar?==?section)?{ ??
- ????????????????????return?i?+?1; ??
- ????????????????} ??
- ??
- ????????????} ??
- ????????} ??
- ????????mContent?=?null; ??
- ????????l?=?null; ??
- ????????return?-1; ??
- ????} ??
- }??
import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.SectionIndexer;import android.widget.TextView;public class MyAdapter extends BaseAdapter implements SectionIndexer{ private List<Content> list = null; private Context mContext; private SectionIndexer mIndexer; public MyAdapter(Context mContext, List<Content> list) { this.mContext = mContext; this.list = list; } public int getCount() { return this.list.size(); } public Object getItem(int position) { return null; } public long getItemId(int position) { return position; } public View getView(final int position, View view, ViewGroup arg2) { ViewHolder viewHolder = null; if (view == null) { viewHolder = new ViewHolder(); view = LayoutInflater.from(mContext).inflate(R.layout.item, null); viewHolder.tvTitle = (TextView) view.findViewById(R.id.title); viewHolder.tvLetter = (TextView) view.findViewById(R.id.catalog); view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); } final Content mContent = list.get(position); if (position == 0) { viewHolder.tvLetter.setVisibility(View.VISIBLE); viewHolder.tvLetter.setText(mContent.getLetter()); } else { String lastCatalog = list.get(position - 1).getLetter(); if (mContent.getLetter().equals(lastCatalog)) { viewHolder.tvLetter.setVisibility(View.GONE); } else { viewHolder.tvLetter.setVisibility(View.VISIBLE); viewHolder.tvLetter.setText(mContent.getLetter()); } } viewHolder.tvTitle.setText(this.list.get(position).getName()); return view; } final static class ViewHolder { TextView tvTitle; TextView tvLetter; } public Object[] getSections() { // TODO Auto-generated method stub return null; } public int getSectionForPosition(int position) { return 0; } public int getPositionForSection(int section) { Content mContent; String l; if (section == '!') { return 0; } else { for (int i = 0; i < getCount(); i++) { mContent = (Content) list.get(i); l = mContent.getLetter(); char firstChar = l.toUpperCase().charAt(0); if (firstChar == section) { return i + 1; } } } mContent = null; l = null; return -1; }}
?第四步:编写MainActivity类
?
- import?java.util.ArrayList; ??
- import?java.util.Collections; ??
- import?java.util.List; ??
- ??
- import?android.app.Activity; ??
- import?android.content.Context; ??
- import?android.graphics.PixelFormat; ??
- import?android.os.Bundle; ??
- import?android.view.LayoutInflater; ??
- import?android.view.View; ??
- import?android.view.WindowManager; ??
- import?android.widget.LinearLayout.LayoutParams; ??
- import?android.widget.ListView; ??
- import?android.widget.TextView; ??
- ??
- public?class?MainActivity?extends?Activity?{ ??
- ??
- ????private?ListView?mListView; ??
- ????private?SideBar?indexBar; ??
- ????private?WindowManager?mWindowManager; ??
- ????private?TextView?mDialogText; ??
- ????private?View?head; ??
- ??
- ????@Override??
- ????public?void?onCreate(Bundle?savedInstanceState)?{ ??
- ?????????//启动activity时不自动弹出软键盘 ??
- ????????getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);? ??
- ????????super.onCreate(savedInstanceState); ??
- ????????setContentView(R.layout.activity_main); ??
- ????????mListView?=?(ListView)?this.findViewById(R.id.list); ??
- ????????indexBar?=?(SideBar)?findViewById(R.id.sideBar); ??
- ????????mDialogText?=?(TextView)?LayoutInflater.from(this).inflate(R.layout.list_position,?null); ??
- ????????head?=?LayoutInflater.from(this).inflate(R.layout.head,?null); ??
- ????????mListView.addHeaderView(head); ??
- ????????mDialogText.setVisibility(View.INVISIBLE); ??
- ????????mWindowManager?=?(WindowManager)?getSystemService(Context.WINDOW_SERVICE); ??
- ????????WindowManager.LayoutParams?lp?=?new?WindowManager.LayoutParams( ??
- ????????????????LayoutParams.WRAP_CONTENT,?LayoutParams.WRAP_CONTENT, ??
- ????????????????WindowManager.LayoutParams.TYPE_APPLICATION, ??
- ????????????????WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE ??
- ????????????????????????|?WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, ??
- ????????????????PixelFormat.TRANSLUCENT); ??
- ????????mWindowManager.addView(mDialogText,?lp); ??
- ????????indexBar.setTextView(mDialogText); ??
- ????????//初始化数据 ??
- ????????List<Content>?list?=?new?ArrayList<Content>(); ??
- ????????for?(int?i?=?0;?i?<?10;?i++)?{ ??
- ????????????Content?m; ??
- ????????????if?(i?<?3) ??
- ????????????????m?=?new?Content("A",?"选项"?+?i); ??
- ????????????else?if?(i?<?6) ??
- ????????????????m?=?new?Content("F",?"选项"?+?i); ??
- ????????????else??
- ????????????????m?=?new?Content("D",?"选项"?+?i); ??
- ????????????list.add(m); ??
- ????????} ??
- ????????//根据a-z进行排序 ??
- ????????Collections.sort(list,?new?PinyinComparator()); ??
- ????????//?实例化自定义内容适配类?????? ??
- ????????MyAdapter?adapter?=?new?MyAdapter(this,?list); ??
- ????????//?为listView设置适配 ??
- ????????mListView.setAdapter(adapter); ??
- ????????//设置SideBar的ListView内容实现点击a-z中任意一个进行定位 ??
- ????????indexBar.setListView(mListView);???????? ??
- ????} ??
- ??
- }?