主要是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