We all know that the group header of the default ExpandableListView in Android cannot be fixed on the interface. When scrolling down, it cannot indicate the group to which the child is currently displayed, I searched the internet for a lot of expandablelistviews about the effect of QQ friend groups on Imitation mobile phones, and found that they were not satisfactory. As a result, I improved a little bit on the basis of others. In fact, the principle is similar, it only adds the animation effects to be squeezed out, and it is simpler, but it still does not completely achieve the same effect as QQ. I hope some experts can achieve more realistic effects. Let's take a look at it first:
I have not set ExpandableListView independently to form a new control. Like many friends on the Internet, I listen to the OnScrollListener event. When the group is not in the first position, display the indicator in our header and make its view the same as the view in the group where the current child is located. Then add an event to close the group, that is, the effect of a simple QQ Group of Friends is achieved.
Next let's take a look at the main layout file: main. xml. The following topGroup's FrameLayout is our indicator.
Copy codeThe Code is as follows: <? Xml version = "1.0" encoding = "UTF-8"?>
<FrameLayout xmlns: android = "http://schemas.android.com/apk/res/android"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent">
<ExpandableListView
Android: id = "@ + id/expandableListView"
Android: layout_width = "match_parent"
Android: layout_height = "match_parent">
</ExpandableListView>
<FrameLayout
Android: id = "@ + id/topGroup"
Android: layout_width = "match_parent"
Android: layout_height = "wrap_content"
Android: orientation = "vertical">
</FrameLayout>
</FrameLayout>
The most important part is the following: we listen to the onSroll interface event. When the ListView slides, we handle the event accordingly. There are many comments in the code, so I will not describe it here.Copy codeThe Code is as follows :/**
* Here is very importance for indicator group
*/
Public void onScroll (AbsListView view, int firstVisibleItem,
Int visibleItemCount, int totalItemCount ){
Final ExpandableListView listView = (ExpandableListView) view;
/**
* Calculate point (0, 0)
*/
Int npos = view. pointToPosition (0, 0); // It is actually firstVisibleItem
If (npos = AdapterView. INVALID_POSITION) // if the value of the first position is invalid
Return;
Long pos = listView. getExpandableListPosition (npos );
Int childPos = ExpandableListView. getPackedPositionChild (pos); // obtain the id of the child in the first row
Int groupPos = ExpandableListView. getPackedPositionGroup (pos); // obtain the id of the group in the first row.
If (childPos = AdapterView. INVALID_POSITION) {// The first line does not show child or group. No indicator is required.
View groupView = listView. getChildAt (npos
-ListView. getFirstVisiblePosition (); // view of the first row
IndicatorGroupHeight = groupView. getHeight (); // obtain the group height.
IndicatorGroup. setVisibility (View. GONE); // hide the indicator
} Else {
IndicatorGroup. setVisibility (View. VISIBLE); // The indicator is displayed when the first row is child.
}
// Get an error data, so return now
If (indicatorGroupHeight = 0 ){
Return;
}
// Update the data of indicator group view
If (groupPos! = IndicatorGroupId) {// if the indicator does not display the current group
MAdapter. getGroupView (groupPos, listView. isGroupExpanded (groupPos ),
IndicatorGroup. getChildAt (0), null); // update the indicator to the current group
IndicatorGroupId = groupPos;
Log. e (TAG, PRE + "bind to new group, group position =" + groupPos );
// MAdapter. hideGroup (indicatorGroupId); // we set this group view
// To be hided
// Add a click event for this indicator
IndicatorGroup. setOnClickListener (new OnClickListener (){
Public void onClick (View v ){
// TODO Auto-generated method stub
ListView. collapseGroup (indicatorGroupId );
}
});
}
If (indicatorGroupId =-1) // if the grop id is invalid at this time, return
Return;
/**
* Calculate point (0, indicatorGroupHeight) is shown below to form the push-up effect.
*/
Int showHeight = indicatorGroupHeight;
Int nEndPos = listView. pointToPosition (0, indicatorGroupHeight); // the location of the second item
If (nEndPos = AdapterView. INVALID_POSITION) // if it is invalid, return
Return;
Long pos2 = listView. getExpandableListPosition (nEndPos );
Int groupPos2 = ExpandableListView. getPackedPositionGroup (pos2); // obtain the id of the second group
If (groupPos2! = IndicatorGroupId) {// if it is not equal to the current group of the indicator
View viewNext = listView. getChildAt (nEndPos
-ListView. getFirstVisiblePosition ());
ShowHeight = viewNext. getTop ();
Log. e (TAG, PRE + "update the show part height of indicator group :"
+ ShowHeight );
}
// Update group position
MarginLayoutParams layoutParams = (MarginLayoutParams) indicatorGroup
. GetLayoutParams ();
LayoutParams. topMargin =-(indicatorGroupHeight-showHeight );
IndicatorGroup. setLayoutParams (layoutParams );
}
Download the source code of this Article
Finally, I would like to share with you another code that imitates the iPhone Address Book effect. It is an extension of ListView, with the best effect. We hope that experts can extend ExpandableListView to the same effect.
Source code download