楼主是在平板上测试的,图片稍微有点大,大家看看效果就好
接下来贴源码:
PinnedHeaderExpandableListView.java
要注意的是 在 onGroupClick方法中parent.setSelectedGroup(groupPosition)这句代码的作用是点击分组置顶,
我这边不需要这个效果,QQ也没有用到,所以给注释了,大家如果需要可以解开注释
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 接口 . 列表必须实现此接口 .
*/
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;
/**
* 获取 Header 的状态
* @param groupPosition
* @param childPosition
* @return PINNED_HEADER_GONE,PINNED_HEADER_VISIBLE,PINNED_HEADER_PUSHED_UP 其中之一
*/
int getHeaderState(int groupPosition, int childPosition);
/**
* 配置 Header, 让 Header 知道显示的内容
* @param header
* @param groupPosition
* @param childPosition
* @param alpha
*/
void configureHeader(View header, int groupPosition,int childPosition, int alpha);
/**
* 设置组按下的状态
* @param groupPosition
* @param status
*/
void setGroupClickStatus(int groupPosition, int status);
/**
* 获取组按下的状态
* @param groupPosition
* @return
*/
int getGroupClickStatus(int groupPosition);
}
private static final int MAX_ALPHA = 255;
private HeaderAdapter mAdapter;
/**
* 用于在列表头显示的 View,mHeaderViewVisible 为 true 才可见
*/
private View mHeaderView;
/**
* 列表头是否可见
*/
private boolean mHeaderViewVisible;
private int mHeaderViewWidth;
private int mHeaderViewHeight;
public void 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);
}
/**
* 点击 HeaderView 触发的事件
*/
private void headerViewClick() {
long packedPosition = getExpandableListPosition(this.getFirstVisiblePosition());
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;
/**
* 如果 HeaderView 是可见的 , 此函数用于判断是否点击了 HeaderView, 并对做相应的处理 ,
* 因为 HeaderView 是画上去的 , 所以设置事件监听是无效的 , 只有自行控制 .
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mHeaderViewVisible) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = ev.getX();
mDownY = ev.getY();
if (mDownX <= mHeaderViewWidth && mDownY <= mHeaderViewHeight) {
return true;
}
break;
case MotionEvent.ACTION_UP:
fl