主要是2個功能
1、清單滑動 目前組名始終在上面顯示
2、下拉重新整理
在網上找到相似的例子,修改一些以後,加以整合
以下是關鍵代碼部分
1)組名在前面顯示
private LinearLayout _groupLayout;
public ExpandableListAdapter exAdapter = null;
private int _groupIndex = -1;
public boolean collapse = false;
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
{
firstItemIndex = firstVisibleItem;
//this.visibleItemCount = arg2;
//visibleLastIndex = firstItemIndex + visibleItemCount - 1;
if (exAdapter == null)
exAdapter = this.getExpandableListAdapter();
int ptp = view.pointToPosition(0,0);
if (ptp != AdapterView.INVALID_POSITION)
{
UserListView qExlist = (UserListView) view;
long pos = qExlist.getExpandableListPosition(ptp);
int groupPos = ExpandableListView.getPackedPositionGroup(pos);
int childPos = ExpandableListView.getPackedPositionChild(pos);
if (groupPos < _groupIndex)
{
_groupIndex = groupPos;
if (_groupLayout != null){
_groupLayout.removeAllViews();
_groupLayout.setVisibility(GONE);//這裡設定Gone 為了不讓它遮擋後面header
}
}
else if (groupPos >= _groupIndex)
{
long posNext = qExlist.getExpandableListPosition(ptp+1);
int groupPosNext = ExpandableListView.getPackedPositionGroup(posNext);
int childPosNext = ExpandableListView.getPackedPositionChild(posNext);
final FrameLayout fl = (FrameLayout) getParent();
if(childPosNext < 0)
{
return;
}
JDingDebug.printfSystem("index" + _groupIndex + " pos:" + groupPos + " child:" + childPosNext);
if(_groupIndex == groupPos && groupPos != 0)
{
return;
}
if(groupPos == 0 && childPosNext == 0)
{
return;
}
_groupIndex = groupPos;
// if (_groupLayout != null)
// fl.removeView(_groupLayout);
_groupLayout = (LinearLayout)getExpandableListAdapter().getGroupView(groupPos, true, null, null);
// JDingDebug.printfSystem("_groupLayout:" + _groupLayout);
fl.addView(_groupLayout,fl.getChildCount(), new LayoutParams(
LayoutParams.FILL_PARENT, 40));
_groupLayout.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
JDingDebug.printfSystem("按下");
collapseGroup(_groupIndex);
new Handler().post(new Runnable()
{
@Override
public void run() {
fl.removeViews(1, fl.getChildCount()-1);
}
});
}
});
}
}
}
2)下拉重新整理
private final static int RELEASE_To_REFRESH = 0;
private final static int PULL_To_REFRESH = 1;
private final static int REFRESHING = 2;
private final static int DONE = 3;
private final static int LOADING = 4;
private boolean isRefreshable;
private int firstItemIndex;
private boolean isRecored;
private int startY;
private int state;
private boolean isBack;
// 實際的padding的距離與界面上偏移距離的比例
private final static int RATIO = 3;
private int headContentWidth;
private int headContentHeight;
private LinearLayout headView;
private LayoutInflater inflater;
@Override
public boolean onTouchEvent(MotionEvent event)
{
if (isRefreshable)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
if (firstItemIndex == 0 && !isRecored)
{
isRecored = true;
startY = (int) event.getY();
}
break;
case MotionEvent.ACTION_UP:
if (state != REFRESHING && state != LOADING)
{
if (state == DONE)
{
// 什麼都不做
}
if (state == PULL_To_REFRESH)
{
state = DONE;
resetHeadView();
//changeHeaderViewByState();
//Log.v(TAG, "由下拉重新整理狀态,到done狀态");
}
if (state == RELEASE_To_REFRESH)
{
state = REFRESHING;
//onRefresh();
resetHeadView();
}
}
isRecored = false;
isBack = false;
break;
case MotionEvent.ACTION_MOVE:
int tempY = (int) event.getY();
if (!isRecored && firstItemIndex == 0)
{
isRecored = true;
startY = tempY;
}
if (state != REFRESHING && isRecored && state != LOADING)
{
if (state == RELEASE_To_REFRESH)
{
setSelection(0);
// 往上推了,推到了螢幕足夠掩蓋head的程度,但是還沒有推到全部掩蓋的地步
if (((tempY - startY) / RATIO < headContentHeight)
&& (tempY - startY) > 0)
{
state = PULL_To_REFRESH;
//changeHeaderViewByState();
//Log.v(TAG, "由松開重新整理狀态轉變到下拉重新整理狀态");
}
// 一下子推到頂了
else if (tempY - startY <= 0)
{
state = DONE;
//changeHeaderViewByState();
//Log.v(TAG, "由松開重新整理狀态轉變到done狀态");
}
// 往下拉了,或者還沒有上推到螢幕頂部掩蓋head的地步
else
{
// 不用進行特别的操作,隻用更新paddingTop的值就行了
}
}
// 還沒有到達顯示松開重新整理的時候,DONE或者是PULL_To_REFRESH狀态
if (state == PULL_To_REFRESH)
{
setSelection(0);
// 下拉到可以進入RELEASE_TO_REFRESH的狀态
if ((tempY - startY) / RATIO >= headContentHeight)
{
state = RELEASE_To_REFRESH;
isBack = true;
//changeHeaderViewByState();
//Log.v(TAG, "由done或者下拉重新整理狀态轉變到松開重新整理");
}
// 上推到頂了
else if (tempY - startY <= 0)
{
state = DONE;
//changeHeaderViewByState();
//Log.v(TAG, "由DOne或者下拉重新整理狀态轉變到done狀态");
}
}
// done狀态下
if (state == DONE) {
if (tempY - startY > 0)
{
state = PULL_To_REFRESH;
//changeHeaderViewByState();
}
}
// 更新headView的size
if (state == PULL_To_REFRESH)
{
headView.setPadding(0, -1 * headContentHeight
+ (tempY - startY) / RATIO, 0, 0);
}
// 更新headView的paddingTop
if (state == RELEASE_To_REFRESH)
{
headView.setPadding(0, (tempY - startY) / RATIO
- headContentHeight, 0, 0);
}
}
break;
}
}
return super.onTouchEvent(event);
}
public void resetHeadView()
{
headView.setPadding(0, -1*headContentHeight, 0, 0);
state = DONE;
}
// 此方法直接照搬自網絡上的一個下拉重新整理的demo,此處是“估計”headView的width以及height
private void measureView(View child) {
ViewGroup.LayoutParams p = child.getLayoutParams();
if (p == null)
{
p = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0,
0 + 0, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
DEMO下載下傳
http://download.csdn.net/detail/ff313976/4504777