RefreshView下拉刷新问题
public class RefreshListView extends ListView implements OnScrollListener, OnClickListener{
public interface IListViewState
{
int LVS_NORMAL = 0; // 普通状态
int LVS_PULL_REFRESH = 1; // 下拉刷新状态
int LVS_RELEASE_REFRESH = 2; // 松开刷新状态
int LVS_LOADING = 3; // 加载状态
}
public interface IOnRefreshListener
{
void onRefresh();
}
private View mHeadView;
private TextView mRefreshTextview;
private TextView mLastUpdateTextView;
private ImageView mArrowImageView;
private ProgressBar mHeadProgressBar;
private int mHeadContentWidth;
private int mHeadContentHeight;
private IOnRefreshListener mOnRefreshListener; // 头部刷新监听器
// 用于保证startY的坐标在一个完整的touch事件中只被记录一次
private boolean mIsRecord = false;
// 标记的Y坐标值
private int mStartY = 0;
// 当前视图能看到的第一个项的索引
private int mFirstItemIndex = -1;
// MOVE时保存的Y坐标值
private int mMoveY = 0;
// LISTVIEW状态
private int mViewState = IListViewState.LVS_NORMAL;
private final static int RATIO = 2;
private RotateAnimation animation;
private RotateAnimation reverseAnimation;//旋转变化动画
private boolean mBack = false;
public RefreshListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init(context);
}
public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public void setOnRefreshListener(IOnRefreshListener listener)
{
mOnRefreshListener = listener;
}
private void onRefresh()
{
if (mOnRefreshListener != null)
{
mOnRefreshListener.onRefresh();
}
}
public void onRefreshComplete()
{
mHeadView.setPadding(0, -1 * mHeadContentHeight, 0, 0);
mLastUpdateTextView.setText("上次更新:" + new Date().toLocaleString());
switchViewState(IListViewState.LVS_NORMAL);
}
private void init(Context context)
{
initHeadView(context);
//initLoadMoreView(context);
setOnScrollListener(this);
}
// 初始化headview试图
private void initHeadView(Context context)
{
mHeadView = LayoutInflater.from(context).inflate(R.layout.head, null);
mArrowImageView = (ImageView) mHeadView.findViewById(R.id.head_arrowImageView);
mArrowImageView.setMinimumWidth(60);
mHeadProgressBar= (ProgressBar) mHeadView.findViewById(R.id.head_progressBar);
mRefreshTextview = (TextView) mHeadView.findViewById(R.id.head_tipsTextView);
mLastUpdateTextView = (TextView) mHeadView.findViewById(R.id.head_lastUpdatedTextView);
measureView(mHeadView);
mHeadContentHeight = mHeadView.getMeasuredHeight();
mHeadContentWidth = mHeadView.getMeasuredWidth();
mHeadView.setPadding(0, -1 * mHeadContentHeight, 0, 0);
mHeadView.invalidate();
addHeaderView(mHeadView, null, false);
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);
}
// 初始化footview试图
// private void initLoadMoreView(Context context)
// {
// mFootView= LayoutInflater.from(context).inflate(R.layout.loadmore, null);
//
// mLoadMoreView = mFootView.findViewById(R.id.load_more_view);
//
// mLoadMoreTextView = (TextView) mFootView.findViewById(R.id.load_more_tv);
//
// mLoadingView = mFootView.findViewById(R.id.loading_layout);
//
// mLoadMoreView.setOnClickListener(this);
//
// addFooterView(mFootView);
//
// }
// 此方法直接照搬自网络上的�?��下拉刷新的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);
}
public void onScroll(AbsListView arg0, int firstVisiableItem, int visibleItemCount, int totalItemCount) {
mFirstItemIndex = firstVisiableItem;
}
public void onScrollStateChanged(AbsListView arg0, int arg1) {
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
if (mOnRefreshListener != null)
{
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
doActionDown(ev);
break;
case MotionEvent.ACTION_MOVE:
doActionMove(ev);
break;
case MotionEvent.ACTION_UP:
doActionUp(ev);
break;
default:
break;
}
}
return super.onTouchEvent(ev);
}
private void doActionDown(MotionEvent ev)
{
if(mIsRecord == false && mFirstItemIndex == 0)
{
mStartY = (int) ev.getY();
mIsRecord = true;
}
}
private void doActionMove(MotionEvent ev)
{
mMoveY = (int) ev.getY();
if(mIsRecord == false && mFirstItemIndex == 0)
{
mStartY = (int) ev.getY();
mIsRecord = true;
}
if (mIsRecord == false || mViewState == IListViewState.LVS_LOADING)
{
return ;
}
int offset = (mMoveY - mStartY) / RATIO;
switch(mViewState)
{
case IListViewState.LVS_NORMAL:
{
if (offset > 0)
{
mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);
switchViewState(IListViewState.LVS_PULL_REFRESH);
}
}
break;
case IListViewState.LVS_PULL_REFRESH:
{
setSelection(0);
mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);
if (offset < 0)
{
switchViewState(IListViewState.LVS_NORMAL);
}else if (offset > mHeadContentHeight)
{
switchViewState(IListViewState.LVS_RELEASE_REFRESH);
}
}
break;
case IListViewState.LVS_RELEASE_REFRESH:
{
setSelection(0);
mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);
if (offset >= 0 && offset <= mHeadContentHeight)
{
mBack = true;
switchViewState(IListViewState.LVS_PULL_REFRESH);
}else if (offset < 0)
{
switchViewState(IListViewState.LVS_NORMAL);
}else{
}
}
break;
default:
return;
};
}
private void doActionUp(MotionEvent ev)
{
mIsRecord = false;
mBack = false;
if (mViewState == IListViewState.LVS_LOADING)
{
return ;
}
switch(mViewState)
{
case IListViewState.LVS_NORMAL:
break;
case IListViewState.LVS_PULL_REFRESH:
mHeadView.setPadding(0, -1 * mHeadContentHeight, 0, 0);
switchViewState(IListViewState.LVS_NORMAL);
break;
case IListViewState.LVS_RELEASE_REFRESH:
mHeadView.setPadding(0, 0, 0, 0);
switchViewState(IListViewState.LVS_LOADING);
onRefresh();
break;
}
}
private void switchViewState(int state)
{
switch(state)
{
case IListViewState.LVS_NORMAL:
{
Log.e("!!!!!!!!!!!", "convert to IListViewState.LVS_NORMAL");
mArrowImageView.clearAnimation();
mArrowImageView.setImageResource(R.drawable.arrow);
}
break;
case IListViewState.LVS_PULL_REFRESH:
{
Log.e("!!!!!!!!!!!", "convert to IListViewState.LVS_PULL_REFRESH");
mHeadProgressBar.setVisibility(View.GONE);
mArrowImageView.setVisibility(View.VISIBLE);
mRefreshTextview.setText("下拉可以刷新");
mArrowImageView.clearAnimation();
// 是由RELEASE_To_REFRESH状态转变来的
if (mBack)
{
mBack = false;
mArrowImageView.clearAnimation();
mArrowImageView.startAnimation(reverseAnimation);
}
}
break;
case IListViewState.LVS_RELEASE_REFRESH:
{
Log.e("!!!!!!!!!!!", "convert to IListViewState.LVS_RELEASE_REFRESH");
mHeadProgressBar.setVisibility(View.GONE);
mArrowImageView.setVisibility(View.VISIBLE);
mRefreshTextview.setText("松开获取更多");
mArrowImageView.clearAnimation();
mArrowImageView.startAnimation(animation);
}
break;
case IListViewState.LVS_LOADING:
{
Log.e("!!!!!!!!!!!", "convert to IListViewState.LVS_LOADING");
mHeadProgressBar.setVisibility(View.VISIBLE);
mArrowImageView.clearAnimation();
mArrowImageView.setVisibility(View.GONE);
mRefreshTextview.setText("载入中..");
}
break;
default:
return;
}
mViewState = state;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<!-- ListView的头部 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<!-- 内容 -->
<RelativeLayout
android:id="@+id/head_contentLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="30dp" >
<!-- 箭头图像、进度条 -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" >
<!-- 箭头 -->
<ImageView
android:id="@+id/head_arrowImageView"
android:layout_width="20dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/arrow" />
<!-- 进度条 -->
<ProgressBar
android:id="@+id/head_progressBar"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<!-- 提示、最近更新 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<!-- 提示 -->
<TextView
android:id="@+id/head_tipsTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉刷新"
android:textColor="@color/navajowhite"
android:textSize="15sp" />
<TextView
android:id="@+id/head_lastUpdatedTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上次更新"
android:textColor="@color/gold"
android:textSize="10sp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
如何使用:
package com.kalus.aidl;
import java.util.ArrayList;
import java.util.List;
import com.kalus.aidl.RefreshListView.IOnRefreshListener;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ArrayAdapter;
import android.widget.SimpleAdapter;
public class RefreshActivity extends Activity implements IOnRefreshListener {
RefreshListView listview;
ArrayAdapter<String> mAdapter;
List<String> mData = new ArrayList<String>();
GHandler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.refresh);
initData();
handler = new GHandler();
listview = (RefreshListView) findViewById(R.id.refresh);
listview.setOnRefreshListener(RefreshActivity.this);
mAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1,
mData);
listview.setAdapter(mAdapter);
}
private void initData(){
for(int i=0;i<10;i++){
mData.add("mRefreshView:"+i);
}
}
class GHandler extends Handler{
@Override
public void handleMessage(Message msg) {
if(msg.what == 1){
mAdapter.notifyDataSetChanged();
listview.onRefreshComplete();
}
}
}
@Override
public void onRefresh() {
new Thread(){
@Override
public void run() {
for(int i=10;i<20;i++){
mData.add(0, "mRefreshView:"+i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
handler.sendEmptyMessage(1);
}
}.start();
}
}
该activity的布局是一个RefreshView的布局,即继承的那个布局