The landlord was tested on a flat plate. The picture is a little bit big, everyone look at the effect is good
Next Paste source code:
Pinnedheaderexpandablelistview.java
Note that in the Ongroupclick method Parent.setselectedgroup (groupposition) is the function of the code to click on the group top,
I don't need this effect on my side. QQ is not practical, so to stare. Let's say we need to be able to unravel
Package Com.xiaos.view;import Android.content.context;import Android.graphics.canvas;import Android.util.attributeset;import Android.view.motionevent;import Android.view.view;import Android.view.ViewGroup; Import Android.widget.abslistview;import Android.widget.abslistview.onscrolllistener;import Android.widget.expandablelistadapter;import Android.widget.expandablelistview;import Android.widget.expandablelistview.ongroupclicklistener;public class Pinnedheaderexpandablelistview extends Expandablelistview implements Onscrolllistener,ongroupclicklistener {public Pinnedheaderexpandablelistview (Context Context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); Registerlistener ();} Public Pinnedheaderexpandablelistview (context context, AttributeSet Attrs) {Super (context, attrs); Registerlistener () ;} Public Pinnedheaderexpandablelistview (Context context) {super (context); Registerlistener ();} /** * Adapter interface. The list must implement this interface. */public interface Headeradapter {public static final int PINned_header_gone = 0;public static final int pinned_header_visible = 1;public static final int pinned_header_pushed_up = 2 /** * Gets the status of the Header * @param groupposition * @param childposition * @return Pinned_header_gone,pinned_header_visible,pinn Ed_header_pushed_up one of the */int getheaderstate (int groupposition, int childposition);/** * Configure the header to let the header know what is displayed * @param header * @param groupposition * @param childposition * @param alpha */void Configureheader (View header, int GroupP Osition,int childposition, int alpha);/** * Set the status of group pressed * @param groupposition * @param status */void setgroupclickstatus (in T groupposition, int status);/** * Gets the status of group pressed * @param groupposition * @return */int getgroupclickstatus (int groupposition); }private static final int max_alpha = 255;private headeradapter madapter;/** * Used to display view,mheaderviewvisible in list header is true See */private View mheaderview;/** * List header is visible */private boolean mheaderviewvisible;private int mheaderviewwidth;private int m Headerviewheight;publicvoid Setheaderview (view view) {Mheaderview = view; Abslistview.layoutparams LP = new Abslistview.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); view.setlayoutparams (LP); if (Mheaderview! = null) {setfadingedgelength (0);} Requestlayout ();} private void Registerlistener () {Setonscrolllistener (this); Setongroupclicklistener (this);} /** * Click Headerview triggered event */private void Headerviewclick () {Long packedposition = getexpandablelistposition (this.getFirst Visibleposition ()); int groupposition = Expandablelistview.getpackedpositiongroup (packedposition); if ( Madapter.getgroupclickstatus (groupposition) = = 1) {this.collapsegroup (groupposition); madapter.setgroupclickstatus (groupposition, 0);} Else{this.expandgroup (groupposition); Madapter.setgroupclickstatus (groupposition, 1);} This.setselectedgroup (groupposition);} Private float mdownx;private Float mdowny;/** * Assume headerview is visible, this function is used to infer whether the Headerview is clicked and the corresponding processing is done, * because Headerview is The Set event listener is not valid, only has the self-control. */@Overridepublic boolean ontouchevent (motionevent ev) {if (mheaderviewvisible) {switch (ev.getaction ()) {case MotionEvent.ACTION_DOWN:mDownX = Ev.getx (); mdowny = Ev.gety (); if (Mdownx <= mheaderviewwidth && mdowny <= m Headerviewheight) {return true;} Break;case MotionEvent.ACTION_UP:float x = Ev.getx (); Float y = ev.gety (); Float OffsetX = Math.Abs (x-mdownx); float offset Y = Math.Abs (y-mdowny);//Assuming Headerview is visible, click inside Headerview, then trigger Headerclick () if (x <= mheaderviewwidth &&A mp Y <= mheaderviewheight&& offsetX <= mheaderviewwidth && offsetY <= mheaderviewheight) {if (mHead Erview! = null) {Headerviewclick ();} return true;} Break;default:break;}} return super.ontouchevent (EV);} @Overridepublic void Setadapter (Expandablelistadapter adapter) {Super.setadapter (adapter); madapter = (Headeradapter) adapter;} /** * * Click on the group triggered event, depending on the status of the current click Group */@Overridepublic Boolean ongroupclick (Expandablelistview parent,view v,in T Groupposition,long ID) {if (Madapter.getgroupclickstatus (groupposition) = = 0) {madapter.setgroupclickstatus (groupposition, 1); Parent.expandgroup (groupposition);//header himself//parent.setselectedgroup (groupposition);} else if (madapter.getgroupclickstatus (groupposition) = = 1) {madapter.setgroupclickstatus (groupposition, 0); Parent.collapsegroup (groupposition);} Returns true capable enough to bounce back the first line, not knowing why return true;} @Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (Widthmeasurespec, HEIGHTMEASURESPEC); if (Mheaderview! = null) {Measurechild (Mheaderview, Widthmeasurespec, Heightmeasurespec); Mheaderviewwidth = Mheaderview.getmeasuredwidth (); mheaderviewheight = Mheaderview.getmeasuredheight ();}} private int moldstate =-1; @Overrideprotected void OnLayout (Boolean changed, int left, int top, int right,int bottom) {sup Er.onlayout (changed, left, top, right, bottom); final long flatpostion = Getexpandablelistposition ( Getfirstvisibleposition ()); final int grouppos = Expandablelistview.getPackedpositiongroup (flatpostion); final int childpos = Expandablelistview.getpackedpositionchild (flatPostion); int State = Madapter.getheaderstate (Grouppos, Childpos); if (Mheaderview! = NULL && Madapter! = null && state!) = moldstate) {moldstate = state;mheaderview.layout (0, 0, mheaderviewwidth, mheaderviewheight);} Configureheaderview (Grouppos, childpos);} public void Configureheaderview (int groupposition, int childposition) {if (Mheaderview = = NULL | | madapter = null| | ((Expandablelistadapter) madapter). GetGroupCount () = = 0) {return;} int state = Madapter.getheaderstate (groupposition, childposition); switch (state) {case Headeradapter.pinned_header_ GONE: {mheaderviewvisible = False;break;} Case headeradapter.pinned_header_visible: {madapter.configureheader (Mheaderview, Groupposition,childposition, MAX_ ALPHA); if (Mheaderview.gettop ()! = 0) {mheaderview.layout (0, 0, mheaderviewwidth, mheaderviewheight);} mheaderviewvisible = True;break;} Case HEADERADAPTER.PINNED_HEADER_PUSHED_UP: {View Firstview = getchildat (0), int bottom = Firstview.getbottom ();//Intitemheight = Firstview.getheight (); int Headerh eight = Mheaderview.getheight (); int Y;int alpha;if (Bottom < headerheight) {y = (bottom-headerheight); alpha = Max_alp HA * (headerheight + y)/headerheight;} else {y = 0;alpha = Max_alpha;} Madapter.configureheader (Mheaderview, groupposition,childposition, Alpha); if (Mheaderview.gettop ()! = y) { Mheaderview.layout (0, Y, mheaderviewwidth, mheaderviewheight + y);} mheaderviewvisible = True;break;}}} @Override the/** * List interface is updated when the method is called (such as scrolling) */protected void Dispatchdraw (canvas canvas) {super.dispatchdraw (canvas); mheaderviewvisible) {//group bar is drawn directly into the interface. Instead of adding to ViewGroup drawchild (canvas, Mheaderview, Getdrawingtime ());}} @Overridepublic void Onscroll (abslistview view, int firstvisibleitem,int visibleitemcount, int totalitemcount) {final Long Flatpos = Getexpandablelistposition (firstvisibleitem); int groupposition = Expandablelistview.getpackedpositiongroup (flatpos); int ChildpositiOn = Expandablelistview.getpackedpositionchild (Flatpos); Configureheaderview (Groupposition, childPosition);} @Overridepublic void onscrollstatechanged (abslistview view, int scrollstate) {}}
Pinnedheaderexpandableadapter.java Adapter
Implements the Headeradapter interface in the Pinnedheaderexpandablelistview
Package Com.xiaos.adapter;import Android.content.context;import Android.util.sparseintarray;import Android.view.layoutinflater;import Android.view.view;import Android.view.viewgroup;import Android.widget.baseexpandablelistadapter;import Android.widget.imageview;import Android.widget.TextView;import Com.xiaos.pinnedheaderexpandable.r;import Com.xiaos.view.pinnedheaderexpandablelistview;import Com.xiaos.view.pinnedheaderexpandablelistview.headeradapter;public class Pinnedheaderexpandableadapter extends Baseexpandablelistadapter implements Headeradapter{private string[][] childrendata;private String[] groupData; Private Context context;private Pinnedheaderexpandablelistview listview;private layoutinflater inflater;public Pinnedheaderexpandableadapter (string[][] childrendata,string[] Groupdata,context Context, Pinnedheaderexpandablelistview listView) {this.groupdata = Groupdata; this.childrendata = Childrendata;this.context = Context;this.listview = Listview;inflater = Layoutinflater.from (thiS.context);} @Overridepublic Object getchild (int groupposition, int childposition) {return childrendata[groupposition][ Childposition];} @Overridepublic long Getchildid (int groupposition, int childposition) {return 0;} @Overridepublic view Getchildview (int groupposition, int childposition,boolean islastchild, view Convertview, ViewGroup Parent) {View view = null; if (Convertview! = null) {view = Convertview;} else {view = Createchildrenview ();} TextView Text = (TextView) View.findviewbyid (r.id.childto); Text.settext (Childrendata[groupposition][childposition] ); return view; } @Overridepublic int Getchildrencount (int groupposition) {return childrendata[groupposition].length;} @Overridepublic Object getgroup (int groupposition) {return groupdata[groupposition];} @Overridepublic int GetGroupCount () {return groupdata.length;} @Overridepublic long getgroupid (int groupposition) {return 0;} @Overridepublic View getgroupview (int groupposition, Boolean Isexpanded,view Convertview, ViewGroup parent) {VieW view = null; if (Convertview! = null) {view = Convertview;} else {view = Creategroupview ();} ImageView IV = (ImageView) View.findviewbyid (R.id.groupicon), if (isexpanded) {Iv.setimageresource (r.drawable.btn_ BROWSER2);} Else{iv.setimageresource (R.drawable.btn_browser);} TextView Text = (TextView) View.findviewbyid (R.id.groupto); Text.settext (Groupdata[groupposition]); return view; } @Overridepublic Boolean hasstableids () {return true;} @Overridepublic boolean ischildselectable (int groupposition, int childposition) {return true;} Private View Createchildrenview () {return inflater.inflate (r.layout.child, null);} Private View Creategroupview () {return inflater.inflate (r.layout.group, null);} @Overridepublic int getheaderstate (int groupposition, int childposition) {final int childCount = Getchildrencount ( Groupposition), if (childposition = = childCount-1) {return pinned_header_pushed_up;} else if (childposition = = -1&&am p;!listview.isgroupexpanded (groupposition)) {return pinned_header_gone;} else {return pinned_header_visible;}} @Overridepublic void Configureheader (View header, int groupposition,int childposition, int alpha) {String Groupdata = this . groupdata[groupposition];((TextView) Header.findviewbyid (R.id.groupto)). SetText (Groupdata);} Private Sparseintarray Groupstatusmap = new Sparseintarray (); @Overridepublic void setgroupclickstatus (int groupposition, int status) {Groupstatusmap.put (groupposition, status);} @Overridepublic int getgroupclickstatus (int groupposition) {if (Groupstatusmap.keyat (groupposition) >=0) {return Groupstatusmap.get (groupposition);} else {return 0;}}}
Mainactivity.java main activity
Package Com.xiaos.pinnedheaderexpandable;import Android.app.activity;import Android.os.bundle;import Android.view.view;import Android.widget.expandablelistview;import Android.widget.expandablelistview.ongroupclicklistener;import Com.xiaos.adapter.PinnedHeaderExpandableAdapter; Import Com.xiaos.view.pinnedheaderexpandablelistview;public class Mainactivity extends Activity{private Pinnedheaderexpandablelistview explistview;private string[][] childrendata = new STRING[10][10];p rivate String[] Groupdata = new STRING[10];p rivate int expandflag = -1;//Control List expand private Pinnedheaderexpandableadapter adapter; @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( R.layout.layout_main); Initview (); InitData ();} /** * Initialize view */private void Initview () {Explistview = (Pinnedheaderexpandablelistview) Findviewbyid (R.id.explistview);} /** * Initialize data */private void InitData () {for (int i=0;i<10;i++) {Groupdata[i] = "group" +I;} for (int i=0;i<10;i++) {for (int j=0;j<10;j++) {Childrendata[i][j] = "Friends" +i+ "-" +J;}} Set the suspension head Viewexplistview.setheaderview (Getlayoutinflater (). Inflate (R.layout.group_head,explistview, false)); adapter = new Pinnedheaderexpandableadapter (Childrendata, Groupdata, Getapplicationcontext (), Explistview); Explistview.setadapter (adapter);//Set Individual grouping expansion//explistview.setongroupclicklistener (new Groupclicklistener ());} Class Groupclicklistener implements ongroupclicklistener{@Overridepublic Boolean Ongroupclick (Expandablelistview Parent, View V,int groupposition, long id) {if (Expandflag = =-1) {//Expand selected Groupexplistview.expandgroup (groupposition);// Sets the selected group to be placed at the top Explistview.setselectedgroup (groupposition); expandflag = groupposition;} else if (Expandflag = = groupposition) {explistview.collapsegroup (expandflag); expandflag =-1;} else { Explistview.collapsegroup (Expandflag);//Expand Selected Groupexplistview.expandgroup (groupposition);// Sets the selected group to be placed at the top Explistview.setselectedgroup (groupposition); expandflag = groupposition;} return true;}}}
Layout file
Child.xml
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android " android:layout_width=" match_parent " android:layout_height=" 40dip " android:background=" # FFFFFF "> <imageview android:id=" @+id/groupicon " android:layout_width=" 40DP " android: layout_height= "40DP" android:paddingleft= "10DP" android:src= "@null"/> <textview android : id= "@+id/childto" android:layout_width= "match_parent" android:layout_height= "Match_parent " android:paddingleft= "10DP" android:paddingtop= "10dip" android:textcolor= "#000000" android: Textsize= "16SP"/></linearlayout>
Group_head.xml
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android " android:layout_width=" match_parent " android:layout_height=" wrap_content " android:o rientation= "Horizontal" android:background= "#B8E6FA" android:gravity= "center_vertical" > < ImageView android:id= "@+id/groupicon" android:layout_width= "50DP" android:layout_height= "50DP" android:contentdescription= "@null" android:layout_marginleft= "10DP" android:src= "@drawable/btn_ Browser2 "/> <textview android:id=" @+id/groupto "android:layout_width=" Match_parent " android:layout_height= "50DP" android:textcolor= "#000000" android:textsize= "18sp" android: Gravity= "Center_vertical|left"/></linearlayout>
Group.xml
<?XML version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android " android:layout_width=" match_parent " android:layout_height=" wrap_content " android:orientation=" Horizontal " android:background=" #B8E6FA " android:gravity=" center_vertical "> <imageview Android:id= "@+id/groupicon" android:layout_width= "50DP" android:layout_height= "50DP" android: contentdescription= "@null" android:layout_marginleft= "10DP" android:src= "@drawable/btn_browser"/> <textview android:id= "@+id/groupto" android:layout_width= "match_parent" android:layout _height= "50DP" android:textcolor= "#000000" android:textsize= "18sp" android:gravity= "Center_ Vertical|left "/></linearlayout>
Layout_main.xml
<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android " android:layout_width=" match_parent " android:layout_height=" Match_parent " android: Background= "#F0F0F0" android:orientation= "vertical" > < Com.xiaos.view.PinnedHeaderExpandableListView android:id= "@+id/explistview" android:layout_width= " Match_parent " android:layout_height=" match_parent " android:layout_marginleft=" 0.0dip " android: Cachecolorhint= "#00000000" android:choicemode= "Singlechoice" android:drawselectorontop= "false" Android:fastscrollenabled= "false" android:footerdividersenabled= "true" android:groupindicator= "@null " android:scrollbars=" vertical " android:scrollingcache=" true "/></linearlayout>
Androidmanifest.xml
<manifest xmlns:android= "http://schemas.android.com/apk/res/android" package= " Com.xiaos.pinnedheaderexpandable " android:versioncode=" 1 " android:versionname=" 1.0 "> < USES-SDK android:minsdkversion= "8" android:targetsdkversion= "/> <application android: Allowbackup= "true" android:icon= "@drawable/ic_launcher" android:label= "@string/app_name" android: Theme= "@style/apptheme" > <activity android:name= ". Mainactivity " android:icon=" @drawable/ic_launcher "> <intent-filter> <action android: Name= "Android.intent.action.MAIN"/> <category android:name= "Android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application></manifest>
Two pictures:
: http://download.csdn.net/detail/h7870181/8073677
Android UI View Effect Chapter QQ Friends List group suspension Pinnedheaderexpandablelistview