Android ListView Group and Alphabetical Index navigation (2) Refactoring-interface

Source: Internet
Author: User

The previous article on the ListView Grouping and the letter index navigation implementation idea has done the analysis, and follows the thought step by step realization, finally already better realizes the entire function. But careful study will find that its implementation is not good enough, the main problem:

1. For a widely used layout, the above implementations are not common enough, especially if you need to add some extra fields to the Bo, the fields themselves are meaningless.

2. The code is all mixed up in the activity.

Do some code refactoring for the above two points. First, we optimize it as a generic activity. It's easy to make a generic view, and then extract and refactor the code.

Ideas and ideas

One of the main problems with the previous code is "pollution" of the original Bo, and the main reason for the pollution is the need to use these additional fields for data processing and the generation of list group labels when used.

The original code is as follows:

public class Testbo {     /**     * Primary field */    private String bostr = null;          /**     * bo Pinyin cache */    private String bopinyin = null;    /**     * bo tag tag */    private String botagflag = null;          Public Testbo () {       super ();    }     Public Testbo (String str) {       super ();       This.bostr = str;    }          Public String Getbostr () {       return bostr;    }     public void Setbostr (String bostr) {       this.bostr = bostr;    }     Public String Getsortstrpinyin () {       return bopinyin;    }     public void Setsortstrpinyin (String pinyin) {       this.bopinyin = pinyin;    }     public void Settag (String tag) {       This.botagflag = tag;    }    Public String Gettag () {       return botagflag;    }}


In fact, the above Bo really useful has the main field, the others are additional fields, in fact, the generated list as long as the Bo provided by which field to group on the line.

Naturally we think of the interface, as long as the corresponding interface is implemented, the interface method returns the need to "group sorting values."

Data processing can be changed accordingly.

Refactoring bo-Interface

The following interfaces are extracted first:

Public interface Bosort  {     /**       * @date 2014-9-3    * @Description: Gets the indexed string    * @param      * @return String    *    /public string getsortstr ();    /**      * @date 2014-9-3    * @Description: Gets the index string pinyin, this best can have the cache    * @param      * @return    string    * * Public String Getsortstrpinyin ();       /**      * @date 2014-9-3    * @Description:    * @param      * @return void */public    void Setsortstrpinyin (String pinyin);    /**      * @date 2014-9-3    * @Description: Set tag, need cache    * @param      * @return void */public    void Settag (String tag);    /**      * @date 2014-9-3    * @Description: Gets the label, if NULL, the description is not a label    * @param      * @return String    * * Public String Gettag ();}


The corresponding Bo implements the above interface. But we can provide a default implementation, which is also an abstract class, as long as Bo inherits this default implementation and implements the method for implementation PublicString Getsortstr ();

/**   * @date 2014-9-3 * @Description: Just implement GETSORTSTR other do not modify    */public  abstract class Defaultbosortimp Implements bosort{        /**     * bo Pinyin cache */    private String bopinyin = null;    /**     * bo tag tag */    private String botagflag = null;       /**     * Must have this constructor *     /Public    defaultbosortimp () {       super ();    }     @Override public    String Getsortstrpinyin () {       return bopinyin;    }     @Override public    void Setsortstrpinyin (String pinyin) {       this.bopinyin = pinyin;    }     @Override public    void Settag (String tag) {       This.botagflag = tag;    }    @Override public    String Gettag () {       return botagflag;    }}

Data processing

The overall implementation process is similar to the previous, with a slight change in data processing. We take the data processing separately as a class, visible processing process, the generation of packet labels when the use of reflection, and this data processing only depends on the interface, rather than the specific Bo, reducing the coupling.

public class Rulerutil {/** * list adaptation?? */public static final string[] Indexstr = {"#", "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 "}; public static final char[] letters = {' 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 '}; /** * @throws illegalaccessexception * @throws instantiationexception * @return return processed data * @Description: Processing number According to, sort, add label */public static arraylist<bosort> gensorteddataandtaglocation (list<? extends bosort> MyData , hashmap<string, integer> taglocation) throws Instantiationexception, illegalaccessexception {Ar       raylist<bosort> res = new arraylist<bosort> ();       Res.addall (MyData);          First sort Collections.sort (res, new comparator<bosort> () { @Override public int Compare (Bosort lhs, bosort rhs) {char Firchar = Checkandgetpinyin (LHS);              Char Secchar = Checkandgetpinyin (RHS);              if (Firchar < Secchar) {return-1;              } else if (Firchar > Secchar) {return 1;           } else return 0;        }       });       int size = Res.size ();       int i = 0;             Char Nowtag = ' + ';           for (i = 0; i < size; i++) {Bosort temp = res.get (i);           Char Temptag = checkandgetpinyin (temp);           if (Arrays.binarysearch (Letters, Temptag) < 0) {Temptag = ' # '; } if (Nowtag! = Temptag) {//reflection generate label class<? extends bosort> Boclass = TEMP.GETCL              ();              Bosort Tagbo = Boclass.newinstance ();              Tagbo.settag (temptag+ "");              Res.add (i, Tagbo);              Taglocation.put (Temptag + "", I); i++;             size++;           Nowtag = Temptag;       }} taglocation.put ("#", 0);    return res;       } private static char Checkandgetpinyin (Bosort bo) {String pinyinstr = Bo.getsortstrpinyin ();           if (pinyinstr==null) {Bo.setsortstrpinyin (Hanzitopinyin.getpinyin (Bo.getsortstr ()). toUpperCase ());       Pinyinstr = Bo.getsortstrpinyin ();       } if (Pinyinstr!=null&&pinyinstr.length () >=1) {return Pinyinstr.charat (0);    } return ' to '; }}

Adaptor implementation

The implementation of Adptor is the same as before, but only adaptor is also dependent on the interface and does not depend on the specific Bo.

Refactoring of activity

Constructs a generic abstract activity. When a group navigation is required, it is only necessary to inherit and implement the method of returning the data.

First, the right-hand index is drawn out and made into a view.

1. Rulerwidget

A separate view that can be used directly in the XML layout.


/** * @Description: Right ruler navigation, call Setonrulertouch method to set callback interface */public class Rulerwidget extends linearlayout{private      static final int index_length = RulerUtil.indexStr.length;       Public Rulerwidget (Context context) {super (context);    Init ();       } public Rulerwidget (context context, AttributeSet Attrs) {Super (context, attrs);    Init ();       } public Rulerwidget (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);    Init ();       } private void Init () {int color = getresources (). GetColor (R.color.g_ruler_letter_color); Linearlayout.layoutparams params = new Linearlayout.layoutparams (layoutparams.wrap_content, LayoutParams.WRAP_       CONTENT);       params.gravity = Gravity.center_horizontal;        This.bringtofront ();       Params.weight = 1;           for (int i = 0; i < RulerUtil.indexStr.length; i++) {final TextView TV = new TextView (GetContext ()); Tv.setlayoutparams (params);           Tv.settextcolor (color);           Tv.setgravity (Gravity.center);                  Tv.settext (Rulerutil.indexstr[i]);       This.addview (TV); } this.setontouchlistener (New Ontouchlistener () {@Override public boolean onTouch (View V, Moti              OnEvent event) {int height = v.getheight ();              float pos = event.gety ();              int sectionposition = (int) ((pos/height)/(1f/index_length));              if (Sectionposition < 0) {sectionposition = 0;              } else if (Sectionposition > index_length-1) {sectionposition = index_length-1; } switch (Event.getaction ()) {Case MotionEvent.ACTION_DOWN:if (onrulertouch!                  =null) {Onrulertouch.ondown (sectionposition);                  } RulerWidget.this.setBackgroundResource (r.color.g_ruler_selected);              Break CasE MotionEvent.ACTION_MOVE:if (onrulertouch!=null) {Onrulertouch.onmove (sectionposit                  ION);              } break;                  Default:if (onrulertouch!=null) {onrulertouch.onothers ();              } RulerWidget.this.setBackgroundResource (R.color.g_blank);           } return true;    }       });          }/** * CALLBACK * */private Onrulertouch Onrulertouch;    public void Setonrulertouch (Onrulertouch onrulertouch) {this.onrulertouch = Onrulertouch;     }}/** * @date 2014-9-3 * @Description: Ruler Touch Callback */public interface onrulertouch{public void Ondown (int position);    public void OnMove (int position);    public void Onup (); public void Onothers ();}

2. Activity

An abstract activity. The layout is similar to the previous. Not posted.

/** * @date 2014-9-3 * @Description: Need to implement this method of obtaining data * public abstract list<? Extends bosort> getdatalist ();       */public abstract class Ruleractivity extends activity{protected TextView Nodataview;    protected TextView Rulertag;       protected Progressbarwithtext progress;       Protected ListView ListView;          protected Rulerwidget ruler;    Private Ruleradapter Ruleradapter; Private list<?    Extends bosort> originallist;    Private list<bosort> dealedlist;       Private hashmap<string, integer> taglocation = new hashmap<string, integer> (); /** * */@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (Savedinstanc       EState);       Setcontentview (R.layout.g_ruler);       Findview ();       Initview ();    InitData ();       } private void Findview () {Nodataview = (TextView) Findviewbyid (r.id.g_base_list_nodata);       Rulertag = (TextView) Findviewbyid (R.id.g_ruler_tag); ProgRess = (progressbarwithtext) Findviewbyid (R.id.g_base_progressbar_withtext);       ListView = (ListView) Findviewbyid (R.id.g_base_list);    Ruler = (rulerwidget) Findviewbyid (R.id.g_ruler);       } private void Initview () {progress.setvisibility (view.visible);       Rulertag.setvisibility (View.gone);       Nodataview.setvisibility (View.gone);       Listview.setvisibility (View.gone);    Ruler.setvisibility (View.gone);    } private void InitData () {new Getdataasytask (). Execute (); }/** * @date 2014-9-4 * @Description: Need to implement this method of obtaining data * @param * @return list< Extends bosort> * * public abstract list<?          Extends bosort> getdatalist ();       /** * @date 2014-9-3 * @Description: * @param * @return void */private void Handlesuccessdata () {       Listview.setvisibility (view.visible);       Ruler.setvisibility (view.visible);       Ruleradapter = new Ruleradapter (dealedlist, this); Ruler.setonrulertoUch (New Onrulertouch () {@Override public void Onup () {} @Override Publ           IC void Onothers () {rulertag.setvisibility (view.gone); } @Override public void onMove (int position) {Rulertag.settext (Rulerutil.indexstr[positi              On]);           Listview.setselection (getPosition (position));              } @Override public void Ondown (int position) {rulertag.setvisibility (view.visible);              Rulertag.settext (Rulerutil.indexstr[position]);           Listview.setselection (getPosition (position));             }       });       Listview.setadapter (Ruleradapter);          Ruleradapter.notifydatasetchanged (); }/** * @Description: Gets the position of the list to scroll to when navigating the letter with the touch.     If the touch of the letter, in the label taglocation mapping, does not exist, then look forward.       */Private Integer getPosition (final int j) {Integer pos = null;       int i = j; while (pos = = null && i <= rulerutil.indexstr.length-1) {pos = Taglocation.get (Rulerutil.indexstr[i]);       i++;       } if (pos = = null) {pos = Dealedlist.size ()-1;    } return POS; } class Getdataasytask extends Asynctask<void, Void, void> {@Override protected V           OID OnPreExecute () {super.onpreexecute ();       Progress.setvisibility (view.visible);           } @Override protected void Doinbackground (void ... params) {originallist = Getdatalist ();           try {dealedlist = rulerutil.gensorteddataandtaglocation (originallist, taglocation);              } catch (Exception e) {e.printstacktrace ();                  if (dealedlist!=null) {dealedlist.clear ();              Dealedlist = null;                  } if (Originallist!=null) {originallist.clear ();              Originallist = null; } if (tAglocation!=null) {taglocation.clear ();              Taglocation = null;       }} return null;           } @Override protected void onpostexecute (void result) {progress.setvisibility (view.gone);           Super.onpostexecute (result);              if (dealedlist==null) {nodataview.setvisibility (view.visible);           Return       } handlesuccessdata (); }    }   }

This refactoring is complete.

Android ListView Group and Alphabetical Index navigation (2) Refactoring-interface

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.