listview 도구 클래스: 위로 올리기 새로 고침 + 아래로 내리기 새로 고침

인터넷의 드롭다운 리셋+위로 더 많이 고친 것을 환영합니다. 여러분의 피드백을 환영하고 함께 보완하면 나중에 사용할 때 편리합니다.
package com.tts.dyq.util;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.IInterface;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.tts.dyq.R;

@SuppressLint("SimpleDateFormat")
public class PullToRefreshListView_Both extends ListView implements OnScrollListener {

	private static final String TAG = "listview";
	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;
	//    padding              
	private final static int RATIO = 3;
	private LayoutInflater inflater;
	private LinearLayout headView;
	private TextView tipsTextview;
	private TextView lastUpdatedTextView;
	private ImageView arrowImageView;
	private ProgressBar progressBar;
	private RotateAnimation animation;
	private RotateAnimation reverseAnimation;
	//     startY        touch         
	private boolean isRecored = false;
	private int headContentWidth;
	private int headContentHeight;
	private int firstItemIndex;
	private int state;
	private boolean isBack;
	private OnRefreshListener refreshListener;
	private boolean isRefreshable;

	private LinearLayout footView;
	private TextView m_tipsTextview;
	private TextView m_lastUpdatedTextView;
	private ImageView m_arrowImageView;
	private ProgressBar m_progressBar;
	private boolean m_isRecored = false;
	private int m_headContentWidth;
	private int m_headContentHeight;
	private int startY;
	private int m_firstItemIndex;
	private boolean m_isBack;
	private OnRefreshListener m_refreshListener;
	private boolean mRefreshHead;

	private int mTotalSize;

	public PullToRefreshListView_Both(Context context) {
		super(context);
		init(context);

	}

	private void init(Context context) {
		inflater = LayoutInflater.from(context);
		initHeadView(context);
		initFootView(context);
		initAnimation();
		state = DONE;
		isRefreshable = false;
		setOnScrollListener(this);
	}

	/**
	 *      
	 */
	private void initAnimation() {
		animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		animation.setInterpolator(new LinearInterpolator());
		animation.setDuration(250);
		animation.setFillAfter(true);
		reverseAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
				0.5f);
		reverseAnimation.setInterpolator(new LinearInterpolator());
		reverseAnimation.setDuration(200);
		reverseAnimation.setFillAfter(true);
	}

	public PullToRefreshListView_Both(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	private void initHeadView(Context context) {
		headView = (LinearLayout) inflater.inflate(R.layout.head, null);
		arrowImageView = (ImageView) headView.findViewById(R.id.head_arrowImageView);
		progressBar = (ProgressBar) headView.findViewById(R.id.head_progressBar);
		tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
		lastUpdatedTextView = (TextView) headView.findViewById(R.id.head_lastUpdatedTextView);
		measureView(headView);
		headContentHeight = headView.getMeasuredHeight();
		headContentWidth = headView.getMeasuredWidth();
		headView.setPadding(0, -1 * headContentHeight, 0, 0);
		headView.invalidate();
		Log.v("size", "width:" + headContentWidth + " height:" + headContentHeight);
		addHeaderView(headView, null, false);

	}

	private void initFootView(Context context) {
		footView = (LinearLayout) inflater.inflate(R.layout.foot, null);
		m_arrowImageView = (ImageView) footView.findViewById(R.id.foot_arrowImageView);
		m_progressBar = (ProgressBar) footView.findViewById(R.id.foot_progressBar);
		m_tipsTextview = (TextView) footView.findViewById(R.id.foot_tipsTextView);
		m_lastUpdatedTextView = (TextView) footView.findViewById(R.id.foot_lastUpdatedTextView);
		measureView(footView);
		m_headContentHeight = footView.getMeasuredHeight();
		m_headContentWidth = footView.getMeasuredWidth();
		footView.setPadding(0, -1 * m_headContentHeight, 0, 0);
		footView.invalidate();
		Log.v("size", "width:" + m_headContentWidth + " height:" + m_headContentHeight);
		addFooterView(footView, null, false);
	}

	@Override
	public void onScroll(AbsListView arg0, int firstVisiableItem, int visibleItemCount, int totalItemCount) {
		firstItemIndex = firstVisiableItem;
		mTotalSize = totalItemCount;
		m_firstItemIndex = totalItemCount;

		mIsLast = (firstVisiableItem + visibleItemCount) == totalItemCount ? true : false;
//		Log.e(TAG, "-------onScroll-------mIsLastItemVisible=" + mIsLast);
	}

	private boolean mIsLast = false;

	@Override
	public void onScrollStateChanged(AbsListView arg0, int arg1) {
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// Log.e(TAG, "isRefreshable=" + isRefreshable);
		if (getAdapter() == null)
			return false;

		if (isRefreshable) {
			switch (event.getAction()) {
			//  down      Y   
			case MotionEvent.ACTION_DOWN:
				startY = (int) event.getY();
				// Log.e(TAG, "------x-----startY=" + startY);
				break;
			case MotionEvent.ACTION_UP:
//				Log.e(TAG, "-------------------ACTION_UP-------------------");
				if (mRefreshHead) {
					updateHeadOnUp();
				} else {
					updateFootViewOnUp(event);
				}

			case MotionEvent.ACTION_MOVE:
				int tempY = (int) event.getY();
				// Log.e(TAG, "------ACTION_MOVE-----tempY=" + tempY +
				// " ;startY=" + startY);
				if (tempY > startY) {
					mRefreshHead = true;
					if (firstItemIndex == 0) {
						updateHeadViewOnMove(tempY);
					}

				} else {
					mRefreshHead = false;
					if (mIsLast) {
						updateFootViewOnMove(tempY);
					}
				}

				break;
			}
		}
		return super.onTouchEvent(event);
	}

	private void updateFootViewOnUp(MotionEvent event) {
		Log.e(TAG, "---------foot----up------------status-----------" + state);

		if (state != REFRESHING && state != LOADING) {
			if (state == DONE) {
				//      
//				Log.e(TAG, "--------foot---up-----0------");
				footView.setPadding(0, -1 * m_headContentHeight, 0, 0);
				headView.setPadding(0, -1 * headContentHeight, 0, 0);
			}
			//        , done  
			if (state == PULL_To_REFRESH) {
//				Log.e(TAG, "--------foot---up-----1------");
				state = DONE;
				changeHeaderViewByState();
				Log.v(TAG, "       , done  ");
			}

			if (state == RELEASE_To_REFRESH) {
//				Log.e(TAG, "--------foot---up-----2------");
				state = REFRESHING;
				changeHeaderViewByState();
				onRefresh();
				Log.v(TAG, "       , done  ");
			}
		}
		m_isRecored = false;
		m_isBack = false;
	}

	private void updateHeadOnUp() {
//		Log.e(TAG, "---------head----up-------------------status-----------" + state);
		if (state != REFRESHING && state != LOADING) {
			if (state == DONE) {
//				Log.e(TAG, "----head----up----------0-----");
				//      
				footView.setPadding(0, -1 * m_headContentHeight, 0, 0);
				headView.setPadding(0, -1 * headContentHeight, 0, 0);
			}
			//        , done  
			if (state == PULL_To_REFRESH) {
//				Log.e(TAG, "----head----up---------1------");
				state = DONE;
				changeHeaderViewByState();
				Log.v(TAG, "       , done  ");
			}

			if (state == RELEASE_To_REFRESH) {
//				Log.e(TAG, "----head----up--------2-------");
				state = REFRESHING;
				changeHeaderViewByState();
				onRefresh();
				Log.v(TAG, "       , done  ");
			}
		}
		isRecored = false;
		isBack = false;
	}

	private void changeHeaderViewByState() {
		// Log.e(TAG, "---------changeHeaderViewByState------in----");
		switch (state) {
		//       
		case RELEASE_To_REFRESH:
			if (mRefreshHead) {
				arrowImageView.setVisibility(View.VISIBLE);
				progressBar.setVisibility(View.GONE);
				tipsTextview.setVisibility(View.VISIBLE);
				lastUpdatedTextView.setVisibility(View.VISIBLE);
				arrowImageView.clearAnimation();
				arrowImageView.startAnimation(animation);
				tipsTextview.setText("    ");
				Log.v(TAG, "    ,    ");
			} else {
				// Log.e(TAG, "---------changeHeaderViewByState-----1-----");
				m_arrowImageView.setVisibility(View.VISIBLE);
				m_progressBar.setVisibility(View.GONE);
				m_tipsTextview.setVisibility(View.VISIBLE);
				m_lastUpdatedTextView.setVisibility(View.VISIBLE);
				m_arrowImageView.clearAnimation();
				m_arrowImageView.startAnimation(animation);
				m_tipsTextview.setText("    ");
				Log.v(TAG, "    ,    ");
			}

			break;
		//     
		case PULL_To_REFRESH:
			if (mRefreshHead) {
				progressBar.setVisibility(View.GONE);
				tipsTextview.setVisibility(View.VISIBLE);
				lastUpdatedTextView.setVisibility(View.VISIBLE);
				arrowImageView.clearAnimation();
				arrowImageView.setVisibility(View.VISIBLE);
				//   RELEASE_To_REFRESH      
				//       
				if (isBack) {
					isBack = false;
					arrowImageView.clearAnimation();
					arrowImageView.startAnimation(reverseAnimation);
					tipsTextview.setText("    ");
				} else {
					tipsTextview.setText("    ");
				}

				footView.setPadding(0, -1 * m_headContentHeight, 0, 0);
			} else {
				// Log.e(TAG, "---------changeHeaderViewByState---2-------");
				m_progressBar.setVisibility(View.GONE);
				m_tipsTextview.setVisibility(View.VISIBLE);
				m_lastUpdatedTextView.setVisibility(View.VISIBLE);
				m_arrowImageView.clearAnimation();
				m_arrowImageView.setVisibility(View.VISIBLE);
				//   RELEASE_To_REFRESH      
				//       
				if (m_isBack) {
					m_isBack = false;
					m_arrowImageView.clearAnimation();
					m_arrowImageView.startAnimation(reverseAnimation);
					m_tipsTextview.setText("    ");
				} else {
					m_tipsTextview.setText("    ");
				}
				headView.setPadding(0, -1 * headContentHeight, 0, 0);
			}

			Log.v(TAG, "    ,    ");
			break;
		//       
		case REFRESHING:
			if (mRefreshHead) {

				headView.setPadding(0, 0, 0, 0);
				progressBar.setVisibility(View.VISIBLE);
				arrowImageView.clearAnimation();
				arrowImageView.setVisibility(View.GONE);
				tipsTextview.setText("    ...");
				lastUpdatedTextView.setVisibility(View.VISIBLE);
			} else {
				// Log.e(TAG, "---------changeHeaderViewByState---3-------");
				footView.setPadding(0, 0, 0, 0);
				m_progressBar.setVisibility(View.VISIBLE);
				m_arrowImageView.clearAnimation();
				m_arrowImageView.setVisibility(View.GONE);
				m_tipsTextview.setText("    ...");
				m_lastUpdatedTextView.setVisibility(View.VISIBLE);
			}
			Log.v(TAG, "    ,    ...");
			break;
		//     
		case DONE:
			if (mRefreshHead) {
				firstItemIndex = 0;
				headView.setPadding(0, -1 * headContentHeight, 0, 0);
				progressBar.setVisibility(View.GONE);
				arrowImageView.clearAnimation();
				arrowImageView.setImageResource(R.drawable.goicon);
				tipsTextview.setText("    ");
				lastUpdatedTextView.setVisibility(View.VISIBLE);
			} else {
				// Log.e(TAG, "---------changeHeaderViewByState---4-------");
				m_firstItemIndex = mTotalSize;
				footView.setPadding(0, -1 * m_headContentHeight, 0, 0);
				m_progressBar.setVisibility(View.GONE);
				m_arrowImageView.clearAnimation();
				m_arrowImageView.setImageResource(R.drawable.ic_pulltorefresh_arrow_up);
				m_tipsTextview.setText("    ");
				m_lastUpdatedTextView.setVisibility(View.VISIBLE);

			}
			Log.v(TAG, "    ,done");
			break;
		}
	}

	public void setOnRefreshListener(OnRefreshListener headViewRefreshListener,
			OnRefreshListener footViewRefreshListener) {
		this.refreshListener = headViewRefreshListener;
		this.m_refreshListener = footViewRefreshListener;
		isRefreshable = true;
	}

	public void updateFootViewOnMove(int tempY) {
		Log.e(TAG, "---------------------updateFootViewOnMove------------------------------");

		if (!m_isRecored && m_firstItemIndex == mTotalSize) {
			Log.v(TAG, " move       ");
			m_isRecored = true;
			startY = tempY;
		}
		if (state != REFRESHING && m_isRecored && state != LOADING) {
			//      padding    ,         head,             ,       ,         
			//         
			if (state == RELEASE_To_REFRESH) {
				setSelection(mTotalSize);
				//     ,         head   ,              
				if (((startY - tempY) / RATIO < m_headContentHeight) && (startY - tempY) > 0) {
					state = PULL_To_REFRESH;
					changeHeaderViewByState();
					Log.e(TAG, "                ");
				}
				//        
				else if (startY - tempY <= 0) {
					state = DONE;
					changeHeaderViewByState();
					Log.e(TAG, "          done  ");
				}
				//     ,              head   
				else {
					//          ,    paddingTop     
				}
			}
			//               ,DONE   PULL_To_REFRESH  
			if (state == PULL_To_REFRESH) {
				setSelection(mTotalSize);
				//        RELEASE_TO_REFRESH   
				if ((startY - tempY) / RATIO >= m_headContentHeight) {
					state = RELEASE_To_REFRESH;
					m_isBack = true;
					changeHeaderViewByState();
					Log.e(TAG, " done               ");
				}
				//      
				else if (startY - tempY <= 0) {
					state = DONE;
					changeHeaderViewByState();
					Log.e(TAG, " DOne           done  ");
				}
			}
			// done   
			if (state == DONE) {
				if (startY - tempY > 0) {
					state = PULL_To_REFRESH;
					changeHeaderViewByState();
				}
			}
			//   headView size
			if (state == PULL_To_REFRESH) {
				footView.setPadding(0, -1 * m_headContentHeight + (startY - tempY) / RATIO, 0, 0);
			}
			//   headView paddingTop
			if (state == RELEASE_To_REFRESH) {
				footView.setPadding(0, 10, 0, 0);
			}
		}
		headView.setPadding(0, -1 * headContentHeight , 0, 0);
	}

	public void updateHeadViewOnMove(int tempY) {
		Log.e(TAG, "-------Head----OnMove-----------");

		if (!isRecored && firstItemIndex == 0) {
			Log.v(TAG, " move       ");
			isRecored = true;
			startY = tempY;
		}
		if (state != REFRESHING && isRecored && state != LOADING) {
			//      padding    ,         head,             ,       ,         
			//         
			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, 10, 0, 0);
			}
		}
		footView.setPadding(0, -1 * m_headContentHeight, 0, 0);
	}

	public interface OnRefreshListener {
		public void onRefresh();
	}

	public void onRefreshComplete() {
		if (mRefreshHead) {
			state = DONE;
			SimpleDateFormat format = new SimpleDateFormat("yyyy MM dd   HH:mm");
			String date = format.format(new Date());
			lastUpdatedTextView.setText("    :" + date);
		} else {
			state = DONE;
			SimpleDateFormat format = new SimpleDateFormat("yyyy MM dd   HH:mm");
			String date = format.format(new Date());
			m_lastUpdatedTextView.setText("    :" + date);
		}
		changeHeaderViewByState();
	}

	private void onRefresh() {
		if (mRefreshHead) {
			if (refreshListener != null) {
				refreshListener.onRefresh();
			}
		} else {
			if (m_refreshListener != null) {
				m_refreshListener.onRefresh();
			}
		}
	}

	//                    demo,   “  ”headView width  height
	private void measureView(View child) {
		ViewGroup.LayoutParams p = child.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 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);
	}

	public void setAdapter(BaseAdapter adapter) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy MM dd   HH:mm");
		String date = format.format(new Date());
		if (mRefreshHead) {
			lastUpdatedTextView.setText("    :" + date);
		} else {
			m_lastUpdatedTextView.setText("    :" + date);
		}

		super.setAdapter(adapter);
	}
}

좋은 웹페이지 즐겨찾기