天天看点

android仿QQ列表实现

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

继续阅读