android Listview下拉刷新

本文介绍了一种自定义的带有下拉刷新功能的ListView组件实现方式,该组件支持多种状态展示,并通过监听触摸和滚动事件来触发刷新操作。同时展示了如何在实际应用中集成此组件,包括设置刷新监听器及适配器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.ejoy.customcontrol;

import java.util.Date;
import com.ejoy.android.R;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
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.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.TextView;

public class fwpRefreshListView 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;
	private final static int RATIO = 3;

	private LayoutInflater inflater;
	private LinearLayout headView;
	private TextView tipsTextview;
	private TextView lastUpdatedTextView;
	private ImageView arrowImageView;
	private ImageView progressBar;

	private RotateAnimation animation;
	private RotateAnimation reverseAnimation;
	private boolean isRecored;
 
	private int headContentHeight;

	private int startY;
	private int firstItemIndex;
	private int state;
	private boolean isBack;
	private OnRefreshListener refreshListener;
	private boolean isRefreshable;

	public fwpRefreshListView(Context context) {
		super(context);
		init(context);
	}

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

	private void init(Context context) {
		setCacheColorHint(context.getResources().getColor(
				R.color.color_transparent));
		inflater = LayoutInflater.from(context);
		headView = (LinearLayout) inflater.inflate(R.layout.mylistview_head,
				null);
		arrowImageView = (ImageView) headView
				.findViewById(R.id.head_arrowImageView);
		progressBar = (ImageView) 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(); 

		headView.setPadding(0, -1 * headContentHeight, 0, 0);
		headView.invalidate();

		addHeaderView(headView, null, false);
		setOnScrollListener(this);

		animation = new RotateAnimation(0, -180,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		animation.setInterpolator(new LinearInterpolator());
		animation.setDuration(250);
		animation.setFillAfter(true);

		reverseAnimation = new RotateAnimation(-180, 0,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		reverseAnimation.setInterpolator(new LinearInterpolator());
		reverseAnimation.setDuration(200);
		reverseAnimation.setFillAfter(true);

		state = DONE;
		isRefreshable = false;
	}

	@Override
	public void onWindowFocusChanged(boolean hasWindowFocus) {
		try {
			AnimationDrawable ad = (AnimationDrawable) progressBar.getBackground();
			ad.start();
		} catch (Exception e) {
			
		}
		super.onWindowFocusChanged(hasWindowFocus);
	};
	
	public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,
			int arg3) {
		firstItemIndex = firstVisiableItem;
	}

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

	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;
						changeHeaderViewByState();
					}
					if (state == RELEASE_To_REFRESH) {
						state = REFRESHING;
						changeHeaderViewByState();
						onRefresh();
					}
				}

				isRecored = false;
				isBack = false;

				break;

			case MotionEvent.ACTION_MOVE:
				int tempY = (int) event.getY();

				if (!isRecored && firstItemIndex == 0) {
					Log.v(TAG, "oooooooooooooooooooooooooo");
					isRecored = true;
					startY = tempY;
				}

				if (state != REFRESHING && isRecored && state != LOADING) {
					if (state == RELEASE_To_REFRESH) {

						setSelection(0);
						if (((tempY - startY) / RATIO < headContentHeight)
								&& (tempY - startY) > 0) {
							state = PULL_To_REFRESH;
							changeHeaderViewByState();
						} else if (tempY - startY <= 0) {
							state = DONE;
							changeHeaderViewByState();
						} else {
						}
					}
					if (state == PULL_To_REFRESH) {
						setSelection(0);
						if ((tempY - startY) / RATIO >= headContentHeight) {
							state = RELEASE_To_REFRESH;
							isBack = true;
							changeHeaderViewByState();
						} else if (tempY - startY <= 0) {
							state = DONE;
							changeHeaderViewByState();
						}
					}
					if (state == DONE) {
						if (tempY - startY > 0) {
							state = PULL_To_REFRESH;
							changeHeaderViewByState();
						}
					}
					if (state == PULL_To_REFRESH) {
						headView.setPadding(0, -1 * headContentHeight
								+ (tempY - startY) / RATIO, 0, 0);

					}
					if (state == RELEASE_To_REFRESH) {
						headView.setPadding(0, (tempY - startY) / RATIO
								- headContentHeight, 0, 0);
					}
				}
				break;
			}
		}

		return super.onTouchEvent(event);
	}

	private void changeHeaderViewByState() {
		switch (state) {
		case RELEASE_To_REFRESH:
			arrowImageView.setVisibility(View.VISIBLE);
			progressBar.setVisibility(View.GONE);
			tipsTextview.setVisibility(View.VISIBLE);
			lastUpdatedTextView.setVisibility(View.VISIBLE);

			arrowImageView.clearAnimation();
			arrowImageView.startAnimation(animation);
			// 松开后刷新
			tipsTextview.setText(R.string.pull_to_refresh_release_label);
			break;
		case PULL_To_REFRESH:
			progressBar.setVisibility(View.GONE);
			tipsTextview.setVisibility(View.VISIBLE);
			lastUpdatedTextView.setVisibility(View.VISIBLE);
			arrowImageView.clearAnimation();
			arrowImageView.setVisibility(View.VISIBLE);
			// 下拉刷新
			if (isBack) {
				isBack = false;
				arrowImageView.clearAnimation();
				arrowImageView.startAnimation(reverseAnimation);
				tipsTextview.setText(R.string.pull_to_refresh_pull_label);
			} else {
				tipsTextview.setText(R.string.pull_to_refresh_pull_label);
			}
			break;

		case REFRESHING:

			headView.setPadding(0, 0, 0, 0);

			progressBar.setVisibility(View.VISIBLE);
			arrowImageView.clearAnimation();
			arrowImageView.setVisibility(View.GONE);
			tipsTextview.setText(R.string.pull_to_refresh_refreshing_label);
			lastUpdatedTextView.setVisibility(View.VISIBLE);
			break;
		case DONE:
			headView.setPadding(0, -1 * headContentHeight, 0, 0);
			progressBar.setVisibility(View.GONE);
			arrowImageView.clearAnimation();
			arrowImageView.setImageResource(R.drawable.goicon);
			tipsTextview.setText(R.string.pull_to_refresh_pull_label);
			lastUpdatedTextView.setVisibility(View.VISIBLE);
			break;
		}
	}

	public void setonRefreshListener(OnRefreshListener refreshListener) {
		this.refreshListener = refreshListener;
		isRefreshable = true;
	}

	public interface OnRefreshListener {
		public void onRefresh();
	}

	public void onRefreshComplete() {
		state = DONE;
		lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());
		changeHeaderViewByState();
		invalidateViews();
		setSelection(0);
	}

	public void onRefresh() {
		if (refreshListener != null) {
			refreshListener.onRefresh();
		}
	}

	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);
	}

	public void setAdapter(BaseAdapter adapter) {
		lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());
		super.setAdapter(adapter);
	}

}
应用:
package com.ejoy.android;

import java.util.ArrayList;

import com.ejoy.adpter.AsyncBitmapLoader;
import com.ejoy.adpter.AsyncBitmapLoader.ImageCallBack;
import com.ejoy.common.BaseCommon;
import com.ejoy.customcontrol.fwpRefreshListView;
import com.ejoy.customcontrol.fwpRefreshListView.OnRefreshListener;
import com.ejoy.dal.DALUserFriendHelper;
import com.ejoy.json.HttpConstant;
import com.ejoy.model.UserFriends;
import com.ejoy.utils.ActivityCloseDB;
import com.ejoy.utils.EjoyLog;
import com.ejoy.utils.MessageBox;
import com.ejoy.utils.StringUtils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class FrmMyFriendsActivity extends Activity implements
		OnItemClickListener {
	private Button mReturnButton = null;
	private fwpRefreshListView mNormalListView = null;
	private DALUserFriendHelper mDalUserFriendHelper = null;
	private ArrayList<UserFriends> mList = null;
	private MyFriendsBaseAdapter mMyFriendsBaseAdapter = null;
	private int isActivityCloseDB = ActivityCloseDB.Unknown;
	LoadMyFriendsAsynTask mLoadMyFriendsAsynTask = null;

	/**
	 * 顶部的载入中的布局
	 */
	private LinearLayout topLodingLayout = null;
	private ImageView mtopLoadProgressBar = null;
	private TextView mtopLoadingTextview = null;
	/**
	 * 程序第一次加载
	 */
	private boolean isFristLoading = true;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		this.setContentView(R.layout.frmmyfriendsactivity);
		((CrashApplication) this.getApplication())
				.addActivity(FrmMyFriendsActivity.this);
		findviewbyid();
		RegisterButtonClick();
		mList = new ArrayList<UserFriends>();
		mDalUserFriendHelper = new DALUserFriendHelper(this);

		mNormalListView.setOnItemClickListener(this);
		mNormalListView.setonRefreshListener(new OnRefreshListener() {
			public void onRefresh() {
				mList.clear();
				mLoadMyFriendsAsynTask = null;
				mLoadMyFriendsAsynTask = new LoadMyFriendsAsynTask();
				mLoadMyFriendsAsynTask.execute(0);
			}
		});
		mList = getData();
		mNormalListView.onRefresh();

	}
	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		try {
			AnimationDrawable ad = (AnimationDrawable) mtopLoadProgressBar.getBackground();
			ad.start();
		} catch (Exception e) {
			
		}
		super.onWindowFocusChanged(hasFocus);
	}
	@Override
	protected void onDestroy() {
		if (mDalUserFriendHelper != null) {
			if (mLoadMyFriendsAsynTask.getStatus() == AsyncTask.Status.FINISHED) {
				mDalUserFriendHelper.CloseDb();
				isActivityCloseDB = ActivityCloseDB.AlreadyClosed;
			} else {
				isActivityCloseDB = ActivityCloseDB.UnClosed;
			}
		}
		super.onDestroy();
	}

	ArrayList<UserFriends> getData() {
		try {
			return mDalUserFriendHelper.GetMyFriendsCursor(BaseCommon.mUserid);
		} catch (Exception e) {
			return new ArrayList<UserFriends>();
		}
	}

	private void SkipIntent(int skip) {
		switch (skip) {
		case 1:
			onItemClick(mNormalListView, null, -1, -1);
			break;
		default:
			break;
		}
	}

	private void RegisterButtonClick() {
		mReturnButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				SkipIntent(1);
			}
		});
		this.mtopLoadingTextview.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				if (mtopLoadingTextview.getTag().toString() == "23") {
					mNormalListView.onRefresh();
				} else {

				}
			}
		});
	}

	private void findviewbyid() {
		mNormalListView = (fwpRefreshListView) findViewById(R.id.friends_RefreshListView);
		mReturnButton = (Button) findViewById(R.id.myfriends_Btnreturn);
		topLodingLayout = (LinearLayout) findViewById(R.id.loadingmyfriendsLayout);
		mtopLoadProgressBar = (ImageView) findViewById(R.id.myfriendsfootprogress);
		mtopLoadingTextview = (TextView) findViewById(R.id.myfriendsTipMsg);
	}

	final class MyfriendsViewHolder {
		public ImageView friendLogoImageView;
		public TextView friendNameTextView;
		public TextView friendnoteTextView;
	}

	class MyFriendsBaseAdapter extends BaseAdapter {
		LayoutInflater mInflater = null;
		private AsyncBitmapLoader asyncLoader = null;

		public MyFriendsBaseAdapter(Context mContext) {
			mInflater = LayoutInflater.from(mContext);
			asyncLoader = new AsyncBitmapLoader();
		}

		public int getCount() {
			return mList.size();
		}

		public Object getItem(int position) {
			return mList.get(position);
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			if (mList == null) {
				return null;
			}
			MyfriendsViewHolder holder = null;
			if (convertView == null) {
				holder = new MyfriendsViewHolder();
				convertView = mInflater.inflate(R.layout.myfrienditemlayout,
						null);
				holder.friendLogoImageView = (ImageView) convertView
						.findViewById(R.id.friendlayout_img);
				holder.friendNameTextView = (TextView) convertView
						.findViewById(R.id.friendlayout_name);
				holder.friendnoteTextView = (TextView) convertView
						.findViewById(R.id.friendlayout_note);
				convertView.setTag(holder);
			} else {
				holder = (MyfriendsViewHolder) convertView.getTag();
			}
			UserFriends mUserFriends = mList.get(position);
			holder.friendnoteTextView.setText(mUserFriends.getFriendNote());
			holder.friendNameTextView.setText(mUserFriends
					.getFriendUserNickName());
			try {
				if (mUserFriends.getFriendUserAvatar().trim() != "") {
					final ImageView imageView = holder.friendLogoImageView;
					asyncLoader.loadBitmap(
							imageView,
							HttpConstant.strImagePathString
									+ mUserFriends.getFriendUserAvatar(),
							new ImageCallBack() {
								public void imageLoad(ImageView imageView,
										Bitmap bitmap) {
									if (bitmap == null) {
										imageView
												.setImageResource(R.drawable.defaultperson);
									} else {
										imageView.setImageBitmap(bitmap);
									}
									if (bitmap != null && bitmap.isRecycled()) {
										bitmap.recycle();
									}
								}
							});
				} else {
					holder.friendLogoImageView
							.setImageResource(R.drawable.defaultperson);
				}
			} catch (Exception e) {
				new EjoyLog(FrmMyFriendsActivity.this).error(this.getClass()
						.getName(), StringUtils.FormatStackTrace(e));
				//e.printStackTrace();
			}
			return convertView;
		}
	}

	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		// -选中一个 然后返回前一个页面
		fwpRefreshListView mfwp = (fwpRefreshListView) arg0;
		UserFriends mFriends = (UserFriends) mfwp.getItemAtPosition(arg2);

		Intent intent = new Intent();
		intent.putExtra(
				"Friendsids",
				mFriends != null ? StringUtils.IntString(mFriends
						.getFriendUserID()) : -1);
		intent.putExtra("Friendsname",
				mFriends != null ? mFriends.getFriendUserNickName() : "");
		this.setResult(8082, intent);
		this.finish();
	}

	private class LoadMyFriendsAsynTask extends
			AsyncTask<Integer, String, Integer> {
		ArrayList<UserFriends> aList = new ArrayList<UserFriends>();

		@Override
		protected void onPreExecute() {
			if (isFristLoading) {
				topLodingLayout.setVisibility(View.VISIBLE);
				mtopLoadProgressBar.setVisibility(View.VISIBLE);
				mtopLoadingTextview.setText(R.string.Loading);
				mtopLoadingTextview.setTag("32");
			} else {
				topLodingLayout.setVisibility(View.GONE);
			}

			super.onPreExecute();
		}

		@Override
		protected void onCancelled() {
			if (isFristLoading) {
				topLodingLayout.setVisibility(View.VISIBLE);
				mtopLoadProgressBar.setVisibility(View.VISIBLE);
				mtopLoadingTextview.setText(R.string.Loading);
				mtopLoadingTextview.setTag("32");
			}
			super.onCancelled();
		}

		@Override
		protected Integer doInBackground(Integer... params) {
			try {
				aList = mDalUserFriendHelper
						.GetMyCouponByJson(BaseCommon.mUserid);
			} catch (org.apache.http.conn.ConnectTimeoutException e) {
				return 6;
			} catch (Exception e) {
				//e.printStackTrace();
				new EjoyLog(FrmMyFriendsActivity.this).error(this.getClass()
						.getName(), StringUtils.FormatStackTrace(e));
				return 5;
			}
			return 2;
		}

		@Override
		protected void onPostExecute(Integer result) {
			if (result.intValue() == 2) {
				topLodingLayout.setVisibility(View.GONE);
			} else {
				if (result.intValue() == 6) {
					MessageBox.ShowMakeText(FrmMyFriendsActivity.this, "连接超时");
				}
				topLodingLayout.setVisibility(View.VISIBLE);
				mtopLoadProgressBar.setVisibility(View.GONE);
				mtopLoadingTextview.setText(R.string.LoadingAgain);
				mtopLoadingTextview.setTag("23");
			}
			if (aList.size() > 0) {
				mList = aList;
			}
			mMyFriendsBaseAdapter = new MyFriendsBaseAdapter(
					FrmMyFriendsActivity.this);
			mNormalListView.setAdapter(mMyFriendsBaseAdapter);
			mNormalListView.onRefreshComplete();
			isFristLoading = false;
			if (isActivityCloseDB == ActivityCloseDB.UnClosed) {
				mDalUserFriendHelper.CloseDb();
				isActivityCloseDB = ActivityCloseDB.AlreadyClosed;
			}
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值