Android Custom Component Series "5"--Advanced Practice (2)

Source: Internet
Author: User

The previous part of the "Android Custom Component Series" 5 "-Advanced Practice (1)" Pinnedheaderexpandablelistview "can pull down the implementation of the" realization of the ". Let's take a look at the use of Expandablelistview and achieve the remainder.

Original source: http://blog.csdn.net/singwhatiwanna/article/details/25546871

First, the use of Expandablelistview

Expandablelistview is a sub-class of the ListView, which is extended on the basis of the normal ListView, and the adapter is expandablelistadapter.


Similar to adapter, the implementation of Expandablelistadapter also has the following ways:

1, extended Baseexpandablelistadapter implementation Expandablelistadapter

2. Use Simpleexpandablelistadapter to wrap two list packages into a expandablelistadapter

3. Use Simplecursortreeadapter to wrap the data in the cursor into Simplecursortreeadapter

Let's take a small example in the first way and look at the use of Expandablelistview

Expandablelistadapter adapter = new Baseexpandablelistadapter () {@Overridepublic boolean ischildselectable (int arg0, int arg1) {//TODO auto-generated method Stubreturn false;} @Overridepublic Boolean hasstableids () {//TODO auto-generated method Stubreturn false;} @Overridepublic view Getgroupview (int arg0, Boolean arg1, view arg2, ViewGroup arg3) {//TODO auto-generated method Stubre Turn null;} @Overridepublic long getgroupid (int arg0) {//TODO auto-generated method Stubreturn 0;} @Overridepublic int GetGroupCount () {//TODO auto-generated method Stubreturn 0;} @Overridepublic Object getgroup (int arg0) {//TODO auto-generated method Stubreturn null;} @Overridepublic int getchildrencount (int arg0) {//TODO auto-generated method Stubreturn 0;} @Overridepublic view Getchildview (int arg0, int arg1, Boolean arg2, view Arg3,viewgroup arg4) {//TODO auto-generated Meth OD stubreturn null;} @Overridepublic long Getchildid (int arg0, int arg1) {//TODO auto-generated method Stubreturn 0;} @OverridepubliC Object getchild (int arg0, int arg1) {//TODO auto-generated method Stubreturn null;}}; 
You can see a lot of methods in Baseexpandablelistapdater, the main methods are as follows:

GetGroupCount (): Returns the number of group lists

Getgroupview (): Returned view as a group list item

Getchildrencount (): Returns the number of child list items

Getchildview (): Returned view as a specific group, a specific location for a child list item

Package Com.example.expandablelistviewtest;import Android.app.activity;import Android.os.bundle;import Android.view.gravity;import Android.view.view;import Android.view.viewgroup;import Android.widget.AbsListView; Import Android.widget.baseexpandablelistadapter;import Android.widget.expandablelistadapter;import Android.widget.expandablelistview;import Android.widget.imageview;import Android.widget.linearlayout;import Android.widget.textview;public class Mainactivity extends Activity {@Overrideprotected void OnCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Expandablelistadapter adapter = new Baseexpandablelistadapter () {int[] logos = new int[] {r.drawable.ic_launcher, R.drawable.ic_launcher,r.drawable.ic_launcher};p rivate string[] grouptypes = new string[]{"Computer language", "Human language", "Animal Language"}; Private string[][] Childtypes = new string[][] {{"Java", "C + +", "C", "PHP"},{"Chinese", "English", "Japanese", "French"},{"cuckoo", "bark", "Meow Meow"}};/ /Gets the specified group location, the child list item data at the specified sub-list item @ovErridepublic Object getchild (int groupposition, int childposition) {return childtypes[groupposition][childposition];} @Overridepublic long Getchildid (int groupposition, int childposition) {return childposition;} @Overridepublic int getchildrencount (int groupposition) {return childtypes[groupposition].length;} Private TextView Gettextview () {abslistview.layoutparams LP = new Abslistview.layoutparams ( ViewGroup.LayoutParams.MATCH_PARENT, 64); TextView TextView = new TextView (mainactivity.this); textview.setlayoutparams (LP); Textview.setgravity ( gravity.center_vertical | Gravity.left); textview.setpadding (0, 0, 0); textview.settextsize; return textView;} This method determines the appearance of each sub-option @overridepublic view Getchildview (int groupposition, int childposition,boolean islastchild, view Convertview, ViewGroup parent) {TextView TextView = Gettextview (); Textview.settext (Getchild (groupposition), childposition). toString ()); return TextView;} Gets the group data at the specified group location @overridepublic Object getgroup (int groupposition) {return grouptYpes[groupposition];} @Overridepublic int GetGroupCount () {return grouptypes.length;} @Overridepublic long getgroupid (int groupposition) {return groupposition;} This method determines the appearance of each group option @overridepublic View getgroupview (int groupposition, Boolean isexpanded,view Convertview, ViewGroup Parent) {LinearLayout LL = new LinearLayout (mainactivity.this); ll.setorientation (0); ImageView logo = new ImageView ( Mainactivity.this); Logo.setimageresource (Logos[groupposition]); Ll.addview (logo); TextView TextView = Gettextview (); Textview.settext (Getgroup (groupposition). toString ()); Ll.addview (TextView); return ll;} @Overridepublic boolean ischildselectable (int groupposition,int childposition) {return true;} @Overridepublic Boolean hasstableids () {return true;}}; Expandablelistview Expandlistview = (expandablelistview) Findviewbyid (r.id.list); Expandlistview.setadapter (Adapter );}}
<relativelayout 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 "    android:paddingbottom= "@dimen/activity_vertical_margin"    android:paddingleft= "@dimen/activity_ Horizontal_margin "    android:paddingright=" @dimen/activity_horizontal_margin "    android:paddingtop=" @dimen /activity_vertical_margin "    tools:context=". Mainactivity "><expandablelistview     android:id=" @+id/list "    android:layout_width=" Match_parent "    android:layout_height= "Wrap_content"/></relativelayout>

Second, code Analysis

First look at the OnCreate method:

    @Override public    void OnCreate (Bundle savedinstancestate) {        super.oncreate (savedinstancestate);        Setcontentview (r.layout.main);        Expandablelistview = (Pinnedheaderexpandablelistview) Findviewbyid (r.id.expandablelist);        Stickylayout = (stickylayout) Findviewbyid (r.id.sticky_layout);        InitData ();        adapter = new Myexpandablelistadapter (this);        Expandablelistview.setadapter (adapter);        Expand All group        for (int i = 0, count = Expandablelistview.getcount (); I < count; i++) {            Expandablelistview.expa Ndgroup (i);        }        Expandablelistview.setonheaderupdatelistener (this);        Expandablelistview.setonchildclicklistener (this);        Expandablelistview.setongroupclicklistener (this);        Stickylayout.setongiveuptoucheventlistener (this);    }
The first few lines are very easy, and the above example is almost the same, we just need to focus on the InitData () method and the following lines of the listener function.

InitData () is the simulated data, as follows:

    void InitData () {grouplist = new arraylist<group> ();        Group group = NULL;            for (int i = 0; i < 3; i++) {group = new Group ();            Group.settitle ("group-" + i);        Grouplist.add (group);        } childlist = new arraylist<list<people>> ();            for (int i = 0; i < grouplist.size (); i++) {arraylist<people> childtemp;                if (i = = 0) {childtemp = new arraylist<people> ();                    for (int j = 0; J <; J + +) {People people = new people ();                    People.setname ("yy-" + j);                    People.setage (30);                    People.setaddress ("sh-" + j);                Childtemp.add (people);                }} else if (i = = 1) {childtemp = new arraylist<people> ();                    for (int j = 0; J < 8; J + +) {People people = new people (); PeoplE.setname ("ff-" + j);                    People.setage (40);                    People.setaddress ("sh-" + j);                Childtemp.add (people);                }} else {childtemp = new arraylist<people> ();                    for (int j = 0; J <; J + +) {People people = new people ();                    People.setname ("hh-" + j);                    People.setage (20);                    People.setaddress ("sh-" + j);                Childtemp.add (people);        }} childlist.add (Childtemp); }    }
Let's take a look at some of these listening functions.

public class Mainactivity extends Activity implements        Expandablelistview.onchildclicklistener,        Expandablelistview.ongroupclicklistener,        Onheaderupdatelistener, Ongiveuptoucheventlistener {
From the inheritance relationship of activity, Onchildclicklistener and Ongroupclicklistener are the listener functions of Expandablelistview class.

    @Override Public    Boolean Ongroupclick (final Expandablelistview parent, final View V,            int groupposition, final Long id) {        return false;    }    @Override Public    Boolean Onchildclick (expandablelistview parent, View V,            int groupposition, int childposition, Long id) {        toast.maketext (mainactivity.this,                childlist.get (groupposition). Get (Childposition). GetName (), 1 )                . Show ();        return false;    }
Looking at Onheaderupdatelistener, this listener is actually a custom listener in the Expandablelistview (custom) override.

    public void Setonheaderupdatelistener (Onheaderupdatelistener listener) {        Mheaderupdatelistener = listener;        if (listener = = null) {            return;        }        Mheaderview = Listener.getpinnedheader ();        int firstvisiblepos = Getfirstvisibleposition ();        int firstvisiblegrouppos = Getpackedpositiongroup (getexpandablelistposition (Firstvisiblepos));        Listener.updatepinnedheader (Firstvisiblegrouppos);        Requestlayout ();        Postinvalidate ();    }

The Getpinnedheader () method creates (gets) a list header, and then sets the group name of the currently visible child list element through the Updatepinnedheader method.

The function of the Requestlayout () method is that when the view determines that it is no longer suitable for an existing region, the view itself calls this method to require the parent view to re-invoke his onmeasure onlayout to reset his position. Especially when the layoutparameter of a view changes and its value is not applied to the view, this is the appropriate method to call.

The function of the Postinvalidate () method is to implement an interface refresh.

   Public interface Onheaderupdatelistener {        /**         * Returns the same View object in singleton mode         * Note: view must have layoutparams */         Public        View Getpinnedheader ();        public void Updatepinnedheader (int firstvisiblegrouppos);    }
From the definition of the Onheaderupdatelistener listener function, the implementation of the two methods is invoked when the listener is triggered as follows:

    @Override public    View Getpinnedheader () {        if (Mheaderview = = null) {            Mheaderview = (viewgroup) Getlayoutinflater (). Inflate (r.layout.group, null);            Mheaderview.setlayoutparams (New Layoutparams (                    layoutparams.match_parent, layoutparams.wrap_content));        }        return mheaderview;    }

    @Override public    void Updatepinnedheader (int firstvisiblegrouppos) {        Group Firstvisiblegroup = (group) Adapter.getgroup (Firstvisiblegrouppos);        TextView TextView = (TextView) getpinnedheader (). Findviewbyid (R.id.group);        Textview.settext (Firstvisiblegroup.gettitle ());    }
Next we need to know what will trigger this listener function.

 protected        void Refreshheader () {if (Mheaderview = = null) {return;        } int firstvisiblepos = Getfirstvisibleposition ();        int pos = Firstvisiblepos + 1;        int firstvisiblegrouppos = Getpackedpositiongroup (getexpandablelistposition (Firstvisiblepos));        int group = Getpackedpositiongroup (Getexpandablelistposition (POS));            if (group = = Firstvisiblegrouppos + 1) {View view = Getchildat (1);                if (View.gettop () <= mheaderheight) {int delta = mheaderheight-view.gettop ();            Mheaderview.layout (0,-delta, Mheaderwidth, Mheaderheight-delta);        }} else {mheaderview.layout (0, 0, mheaderwidth, mheaderheight);        } if (Mheaderupdatelistener! = null) {Mheaderupdatelistener.updatepinnedheader (firstvisiblegrouppos); }    }
You can see that the Updatepinnerheader method is triggered when you call the Refreshheader () method again.

    @Override public    void Onscroll (abslistview view, int firstvisibleitem,            int visibleitemcount, int Totalitemcount) {        if (Totalitemcount > 0) {            refreshheader ();        }        if (Mscrolllistener! = null) {            mscrolllistener.onscroll (view, Firstvisibleitem, VisibleItemCount, Totalitemcount) ;        }    }
Oh, this finally dawned, in the Onscroll method called the Refreshheader, which is said in the sliding screen when the Onheaderupdatelistener monitoring will trigger, will continue to determine whether the column name should be changed.

It's almost 1 o'clock in the morning, so let's analyze it today and continue tomorrow.


Again, this article is to learn about Android custom components, the teacher's blog "can pull down the implementation of the Pinnedheaderexpandablelistview" for a detailed interpretation, if there are questions to point out.

Original source: http://blog.csdn.net/singwhatiwanna/article/details/25546871













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.