Android ui--Group + hover ListView

Source: Internet
Author: User

A ListView that allows the head to hover is often used in a project, such as a friend list for QQ or a regional selection.

Not much to say, see: (Lazy on the GIF picture)



I've done some analysis here, drawing on the core code of others.
The main use of Pinnedsectionlistview is to replace the ListView.
The pinnedsectionlistview here is someone else's. We mainly look at how to use this pinnedsectionlistview and how to fit the data into it.

At the end of the blog post I will upload a demo with Pinnedsectionlistview and complete items. You can follow this blog to see how the data fit in.

First look at the project structure chart:

Which: Pinnedsectionlistview is the same as the others
The other is the class that fits the ListView and the data

1,activity

The activity is simple.

 Public  class indexactivity extends appcompatactivity {    PrivatePinnedsectionlistview pinned_section_list;PrivateIndexadapter Indexadapter;PrivateList<citybean> data;@Override     Public void onCreate(@Nullable Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate); Setcontentview (R.layout.activity_main);//Instantiate a control with a hover headerPinned_section_list = (Pinnedsectionlistview) Findviewbyid (r.id.pinned_section_list);//Analog datadata =NewTestData (). InitData ();//Initialize adapterIndexadapter =NewIndexadapter ( This, data);//Add AdapterPinned_section_list.setadapter (Indexadapter); }}
2,xml layout
<?xml version= "1.0" encoding= "Utf-8"?><relativelayout xmlns:android="Http://schemas.android.com/apk/res/android" android:layout_width="Match_parent"android:layout_height="Match_parent" >            <com.android.list.PinnedSectionListViewandroid:id="@+id/pinned_section_list" android:layout_width="Match_parent"android:layout_height="Match_parent" Android:divider="@null"android:footerdividersenabled="false"  android:headerdividersenabled="false" />                                                </relativelayout>
3, City entity class
publicclass CityBean {    privateint cityId;//城市id    private String cityName;//城市名    privateint superiorId;//上级城市id    private List<CityBean> subordinateList;//下级城市集合    //忽略get/set方法    }
4, test data, simulate city data
 Public classTestData {PrivateList<citybean> data; PublicList<citybean>InitData() {data =NewArraylist<> (); for(intj =1; J < One; J + +) {list<citybean> beijinglist =NewArraylist<> (); for(inti =1; I < One; i++) {Citybean Citybean =NewCitybean (); Citybean.setcityid (i +Ten); Citybean.setcityname ("Beijing"+ i +"Area");            Beijinglist.add (Citybean); } Citybean Citybean =NewCitybean (); Citybean.setcityid (1); Citybean.setcityname ("Beijing", M);            Citybean.setsubordinatelist (beijinglist);            Data.add (Citybean); List<citybean> shanghailist =NewArraylist<> (); for(inti =1; I < One; i++) {Citybean CityBean1 =NewCitybean (); Citybean1.setcityid (i + -); Citybean1.setcityname ("Shanghai"+ i +"Area");            Shanghailist.add (CITYBEAN1); } Citybean CityBean1 =NewCitybean (); Citybean1.setcityid (2); Citybean1.setcityname ("Shanghai"+ j);            Citybean1.setsubordinatelist (shanghailist);            Data.add (CITYBEAN1); List<citybean> shenzhenlist =NewArraylist<> (); for(inti =1; I < One; i++) {Citybean cityBean2 =NewCitybean (); Citybean2.setcityid (i + -); Citybean2.setcityname ("Shenzhen"+ i +"Area");            Shenzhenlist.add (CITYBEAN2); } Citybean cityBean2 =NewCitybean (); Citybean2.setcityid (3); Citybean2.setcityname ("Shenzhen", M);            Citybean2.setsubordinatelist (shenzhenlist);        Data.add (CITYBEAN2); }returnData }}
5,item class, the object that is actually displayed in the ListView
 Public  class Item {     Public Static Final intITEM =0;//Determine if it is a normal item     Public Static Final intSection =1;//Determine if the item you want to hover on is pinned     Public Final intType//External incoming type, item or section     Public FinalCitybean Citybean;//external incoming data, here we write it as a city entity class, can be arbitrarily replaced     Public intSectionposition;//head mark, usually with the ID tag of the parent data     Public intListposition;//Set tag, usually tagged with its own ID     Public Item(intType, Citybean Citybean) { This. type = type; This. Citybean = Citybean; }//Get the data saved     PublicCitybeanGetcitybean() {returnCitybean; }}

The item class is used to hold data that is passed in externally and to set whether the type of the data belongs to the hover header or plain item.

6, the most important, adapter

The adapter for the hover ListView must implement the interface in Pinnedsectionlistview: Pinnedsectionlistadapter and Android Native interface: Sectionindexer

 Public  class indexadapter extends baseadapter  implements  Pinnedsectionlistview. pinnedsectionlistadapter, sectionindexer {    //In order to distinguish the background color of the head, can also be replaced by other means. Example: Layout style    Private Static Final int[] COLORS =New int[]{r.color.green_light, R.color.orange_light, R.color.blue_light, r.color.red_light};PrivateList<citybean> data;//raw data sent in externally    Privatelist<item> items;//This is the list that is actually displayed    PrivateContext context;PrivateItem[] sections;//Header tag Array     Public Indexadapter(context context, list<citybean> data) { This. data = data; This. Context = Context;    Initsection (); }//Initialize display data    Private void initsection() {items =NewArraylist<> (); Sections =NewItem[data.size ()];//Data Preparation         for(inti =0; I < data.size (); i++) {//Add header information to pass in header tags and dataItem section =NewItem (Item.section, Data.get (i)); Section.sectionposition = Data.get (i). Getcityid ();//The parent City ID is passed in as the header ID, because the parent class ID does not have a superior city, so it passes its own IDSection.listposition = Data.get (i). Getcityid ();//pass in its own ID, passing the current city ID as a normal ID            The tag of the city ID in the//header tag group corresponds to the item instance in the citySections[section.sectionposition] = section; Items.Add (section);//Subordinate cities of the current city             for(intj =0; J < Data.get (i). Getsubordinatelist (). Size (); J + +) {//subordinate city for normal ITEM, so incoming Item.itemItem item =NewItem (Item.item, Data.get (i). Getsubordinatelist (). Get (j)); Item.sectionposition = Data.get (i). Getcityid ();//Pass in the parent city ID as the header ID to prove which city belongs to the parent city under the ordinary IDItem.listposition = Data.get (i). Getsubordinatelist (). Get (J). Getcityid ();//pass in its own ID, passing the current city ID as a normal IDItems.Add (item); }        }    }/************************* * The following is the Pinnedsectionlistview override method *************************************************/< /c4>    //Current view is a fixed item    @Override     Public Boolean isitemviewtypepinned(intViewType) {returnViewType = = Item.section; }/************************* * The following is the adapter override method *************************************************/    number of incoming view types, indicating several view types    //pinnedsectionlistview If adapter getviewtypecount<2 is found to throw an exception    @Override     Public int Getviewtypecount() {return 2; }//Returns the type of each view    @Override     Public int Getitemviewtype(intPosition) {returnGetItem (position). type; }@Override     Public int GetCount() {returnItems.size (); }@Override     PublicItemGetItem(intPosition) {returnItems.get (position); }@Override     Public Long Getitemid(intPosition) {returnPosition }@Override     PublicViewGetView(intPosition, view view, ViewGroup parent) {View V;        Viewholder VH; Item item = items.get (position);//Get the current row's data from the collection        if(View = =NULL) {//indicates that the current line is not reusable            //Load line layout file to produce a specific linev = view.inflate (context, R.layout.item,NULL);//Create an object that stores a row of controlsVH =NewViewholder ();//Save all the controls in the row to VHVh.tvname = (TextView) V.findviewbyid (R.id.text_text); V.settag (VH);//Store VH in the row's tag}Else{v = view;//Remove the tag--in a hidden row take out the VH control cache object hidden in this rowVH = (Viewholder) view.gettag (); }//Change the value of a control from a Viewholder cached control        //This is mainly to avoid the waste of resources caused by multiple forced conversion of target objectsVh.tvName.setText (Item.getcitybean (). Getcityname ());if(Item.type = = item.section)        {V.setbackgroundcolor (Parent.getresources (). GetColor (colors[item.sectionposition% colors.length])); }returnV }//Store controls in one row (caching)---Avoid multiple strong turns on each row of controlsClass Viewholder {TextView tvname; }/************************ * The following is an overriding method of the Sectionindexer interface ******************************************/    //Returns an array of objects representing the part of the list used to display the header    //The item[returned here] is the part of the head that is loaded    @Override     PublicItem[]getsections() {returnSections }A partial object within the array of the given index part, returning the starting position in the adapter section.     @Override     Public int getpositionforsection(intSectionindex) {//Avoid throwing Exceptions        if(Sectionindex >= sections.length) {Sectionindex = sections.length-1; }//Returns the header ID of the current header collection        returnSections[sectionindex].listposition; }//Given a position within an adapter, returns a portion of the object within the corresponding index part array.     @Override     Public int getsectionforposition(intPosition) {if(Position >= GetCount ()) {position = GetCount ()-1; }//Returns the header ID saved in the current item        returnGetItem (position). sectionposition; }}

This is the code for the whole project, and it's interesting to see how Pinnedsectionlistview is implemented. I saw part of it because the time relationship did not go on.

Demo download

Android ui--Group + hover ListView

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.