Many people have used listviewfilter this open source list, did quite well, but in the process of use seems a bit of a bug, when clicking on the right side of the letter, will always trigger the list of one of the item's click event, here is the solution to this bug, Mainly Indexbarview.java and Pinnedheaderlistview.java these two files:
1. Pinnedheaderlistview.java
public class Pinnedheaderlistview extends ListView implements Iindexbarfilter {//interface object that configure Pinn Ed header view position in List view Ipinnedheader madapter; View Objects View Mheaderview,mindexbarview,mpreviewtextview; Flags that decide view visibility Boolean mheadervisibility=false; Boolean mpreviewvisibility=false; Initially show index bar view with it s content Boolean mindexbarvisibility=true; Context ObjectContext Mcontext; View height and widthint mheaderviewwidth, Mheaderviewheight, Mindexbarviewwidth, Mindexbarviewheight, Mindexbarviewmargin, Mpreviewtextviewwidth, mpreviewtextviewheight; Touched index bar Y axis position used to decide preview text view position float mindexbary; Public Pinnedheaderlistview (Context context) {super (context); This.mcontext = context; } public Pinnedheaderlistview (context context, AttributeSet attrs) {Super (context, attrs); This.mcontext = context; } public Pinnedheaderlistview (context context, AttributeSet attrs, int defstyle) {Super (context, ATTRS, Def Style); This.mcontext = context; } @Override public void Setadapter (ListAdapter adapter) {This.madapter = (pinnedheaderadapter) adapte R Super.setadapter (adapter); } public void Setpinnedheaderview (View headerview) {this.mheaderview = Headerview; Disable vertical Fading when the pinned header was present//TODO change ListView to allow separate measures for Top and bottom fading edge; In this particular case we would like to disable the top and not the bottom edge. if (Mheaderview! = null) {setfadingedgelength (0); }} public void Setindexbarview (View indexbarview) {mindexbarviewmargin = (int) mcontext.getresources (). getdi Mension (r.dimen.index_bar_view_margin); This.mindeXbarview = Indexbarview;} public void Setpreviewview (View previewtextview) {This.mpreviewtextview=previewtextview;} @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (widthmeasuresp EC, HEIGHTMEASURESPEC); if (Mheaderview! = null) {Measurechild (Mheaderview, Widthmeasurespec, Heightmeasurespec); Mheaderviewwidth = Mheaderview.getmeasuredwidth (); Mheaderviewheight = Mheaderview.getmeasuredheight (); } if (Mindexbarview! = null && mindexbarvisibility) {measurechild (Mindexbarview, WI Dthmeasurespec, Heightmeasurespec); Mindexbarviewwidth = Mindexbarview.getmeasuredwidth (); Mindexbarviewheight = Mindexbarview.getmeasuredheight (); } if (Mpreviewtextview! = null && mpreviewvisibility) {measurechild (MPREVIEWTEXTV Iew, Widthmeasurespec, Heightmeasurespec); Mpreviewtextviewwidth = Mpreviewtextview.getmeasuredwidth (); Mpreviewtextviewheight = Mpreviewtextview.getmeasuredheight (); }} @Override protected void OnLayout (Boolean changed, int left, int top, int. right, int bottom) {super. OnLayout (changed, left, top, right, bottom); if (Mheaderview! = null) {mheaderview.layout (0, 0, mheaderviewwidth, mheaderviewheight); Configureheaderview (Getfirstvisibleposition ()); } if (Mindexbarview! = null && mindexbarvisibility) {mindexbarview.layout (Getmeasuredwidth ()-M Indexbarviewmargin-mindexbarviewwidth, Mindexbarviewmargin, Getmeasuredwidth ()-Mindexbarviewmargin, Getmeasuredheight ()-mindexbarviewmargin); } if (Mpreviewtextview! = null && mpreviewvisibility) {mpreviewtextview.layout (Mindexbarview.getleft ()- Mpreviewtextviewwidth, (int) mindexbary-(MPREVIEWTEXTVIEWHEIGHT/2), Mindexbarview.getleft (), (int) (mIndexBarY-( MPREVIEWTEXTVIEWHEIGHT/2)) +mpreviEwtextviewheight); }} public void Setindexbarvisibility (Boolean isVisible) {if (isVisible) {Mindexbarvisibi Lity=true; } else {mindexbarvisibility=false; }} private void Setpreviewtextvisibility (Boolean isVisible) {if (isVisible) {mpreviewvisibility= True } else {mpreviewvisibility=false; }} public void Configureheaderview (int position) {if (Mheaderview = = null) {return; } int state = madapter.getpinnedheaderstate (position); Switch (state) {case IPinnedHeader.PINNED_HEADER_GONE:mHeaderVisibility = false; Break Case IPinnedHeader.PINNED_HEADER_VISIBLE:if (mheaderview.gettop ()! = 0) {Mheaderview. Layout (0, 0, mheaderviewwidth, mheaderviewheight); } Madapter.configurEpinnedheader (Mheaderview, position); Mheadervisibility = true; Break Case IPinnedHeader.PINNED_HEADER_PUSHED_UP:View Firstview = getchildat (0); int bottom = Firstview.getbottom (); int itemheight = Firstview.getheight (); int headerheight = Mheaderview.getheight (); int y; if (bottom < headerheight) {y = (bottom-headerheight); } else {y = 0; } if (Mheaderview.gettop ()! = y) {mheaderview.layout (0, Y, MHEADERVIEWWI DTH, Mheaderviewheight + y); } madapter.configurepinnedheader (Mheaderview, position); Mheadervisibility = true; Break }} @Override protected void Dispatchdraw (canvas canvas) {super.dispatchdraw (canvas);//Draw List View elements (ZIndex = = 1) if (Mheaderview! = null && mheadervisibility) {Drawchild (ca Nvas, Mheaderview, Getdrawingtime ()); Draw pinned Header view (ZIndex = = 2)} if (Mindexbarview! = null && mindexbarvisibility) {Draw Child (Canvas, Mindexbarview, Getdrawingtime ()); Draw Index Bar view (ZIndex = = 3)} if (Mpreviewtextview! = null && mpreviewvisibility) {DRA Wchild (Canvas, Mpreviewtextview, Getdrawingtime ()); Draw Preview Text view (ZIndex = 4)}} @Overridepublic Boolean ontouchevent (motionevent ev) {if (mindexba Rview! = null && ((Indexbarview) mindexbarview). Ontouchevent (EV)) {setpreviewtextvisibility (true); return True ;} <span style= "color: #ff0000;" >else {if (ev.getaction () = = motionevent.action_up) {setpreviewtextvisibility (false);//Hide Hint textviewinvalidate () ;} if ((Indexbarview) mindexbarview). Istouchside (EV)) return true;//If you click on the Sidebar, digest the current event return Super.ontoucHevent (EV);} </span>} @Overridepublic void filterlist (float indexbary, int position,string previewtext) {this.mindexbary= Indexbary;if (Mpreviewtextview instanceof TextView) ((TextView) mpreviewtextview). SetText (Previewtext); setselection (position);}}
2.indexbarview.java
public class Indexbarview extends View {//index bar margin float mindexbarmargin; User touched Y axis coordinate value float msideindexy; Flag used in touch events manipulations Boolean misindexing = false; Holds current sections position selected by user int mcurrentsectionposition =-1; Array list to store sections positions public arraylist<integer> mlistsections; Array list to store listView data arraylist<musicinfor> mlistitems; Paint object Paint Mindexpaint; Context object Context Mcontext; Interface object used as bridge between List view and index bar view for//Filtering list view content on Touch Eve NT Iindexbarfilter Mindexbarfilter; Public Indexbarview (Context context) {super (context); This.mcontext = context; } public Indexbarview (context context, AttributeSet Attrs) {Super (context, attrs); This.mcontext = context; } Public Indexbarview (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); This.mcontext = context; } public void SetData (Pinnedheaderlistview listView, arraylist<musicinfor> listitems,arraylist<integer> listsections) {this.mlistitems = ListItems; This.mlistsections = listsections; List view implements Mindexbarfilter interface Mindexbarfilter = ListView; Set index bar margin from resources Mindexbarmargin = Mcontext.getresources (). Getdimension (R.dimen.index_bar_vie W_margin); Index bar item color and text Size Mindexpaint = new Paint (); Mindexpaint.setcolor (Mcontext.getresources (). GetColor (R.color.text_black_off)); Mindexpaint.setantialias (TRUE); Mindexpaint.settextsize (Mcontext.getresources (). Getdimension (r.dimen.index_bar_view_text_size)); }//Draw view content on canvas using paint @Override proteCTED void OnDraw (canvas canvas) {if (mlistsections! = null && mlistsections.size () > 1) { float Sectionheight = (getmeasuredheight ()-2 * mindexbarmargin)/mlistsections.size (); float paddingtop = (Sectionheight-(Mindexpaint.descent ()-mindexpaint.ascent ()))/2; for (int i = 0; i < mlistsections.size (); i++) {Float paddingleft = (getmeasuredwidth ()-M Indexpaint.measuretext (Getsectiontext (Mlistsections.get (i)))/2; Canvas.drawtext (Getsectiontext (Mlistsections.get (i)), Paddingleft, Mindexbar Margin + (Sectionheight * i) + paddingtop + mindexpaint.descent (), mindexpaint); }} super.ondraw (canvas); Public String getsectiontext (int sectionposition) {return mlistitems.get (sectionposition). Getsortlett ERS (); } private Boolean contains (float x, float y) {//Determine if the point was in index bar region, which includes the//right margin of the bar Return (x >= getLeft () && y >= getTop () && y <= getTop () + getmeasuredheight ()); } <span style= "color: #ff0000;" >public boolean istouchside (motionevent ev) {return contains (Ev.getx (), ev.gety ()); }</span> void Filterlistitem (float sideindexy) {msideindexy = sideindexy; The filter list items and get touched sections position with in index bar mcurrentsectionposition = (int) ((msideind ExY)-GetTop ()-Mindexbarmargin)/((Getmeasuredheight ()-(2 * mindexbarmargin))/M Listsections.size ())); if (mcurrentsectionposition >= 0 && mcurrentsectionposition < mlistsections.size ()) {int Position = Mlistsections.get (mcurrentsectionposition); String Previewtext = mlistitems.get (position). Getsortletters (); Mindexbarfilter.filterlist (msideindexy, Position, previewtext); }} public Boolean ontouchevent (motionevent ev) {switch (ev.getaction ()) {case Mo Tionevent.action_down://If the event occurs inside Index bar region, start indexing if (c Ontains (Ev.getx (), Ev.gety ())) {//It demonstrates that motion event started from I Ndex//Bar misindexing = true; Determine which section of the point was in, and move the//list to// Filterlistitem (Ev.gety ()); return true; } else {mcurrentsectionposition =-1; return false; } Case MotionEvent.ACTION_MOVE:if (misindexing) {//If this event moves inside index bar if (contains (Ev.getx (), Ev.gety ())) { Determine which section of the point was in, and move the//list to that section Filterlistitem (Ev.gety ()); return true; } else {mcurrentsectionposition =-1; return false; }} break; Case MotionEvent.ACTION_UP:if (misindexing) {misindexing = false; Mcurrentsectionposition =-1; } break; } return false; }}
Complete Project Download: http://download.csdn.net/detail/yuyan19850204/8619085
About the open source project side bar alphabetical Search List Listviewfilter bug resolution