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