天天看點

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

繼續閱讀