PullToRefreshListView进阶(三)----->上拉加载、下拉刷新!

activity_listview_refresh_mani.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".RefreshMainActivity" >

    <com.example.mpulltofresh.RefreshListView
        android:id="@+id/refresh_listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

activity_listview_refresh_header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_margin="5dip" >

        <ImageView
            android:id="@+id/iv_listview_header_down_arrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/common_listview_headview_red_arrow" />

        <ProgressBar
            android:id="@+id/pb_listview_header_progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:indeterminateDrawable="@drawable/custom_progressbar"
            android:visibility="gone" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:gravity="center_horizontal"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/tv_listview_header_state"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="下拉刷新"
            android:textColor="#FF0000"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/tv_listview_header_last_update_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dip"
            android:text="最后刷新时间: 1990-09-09 09:00:00"
            android:textColor="@android:color/darker_gray"
            android:textSize="14sp" />
    </LinearLayout>

</LinearLayout>
activity_listview_refresh_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:padding="5dip" >

        <ProgressBar
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:indeterminateDrawable="@drawable/custom_progressbar" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:text="加载更多..."
            android:textColor="#FF0000"
            android:textSize="20sp" />
    </LinearLayout>

</LinearLayout>

RefreshMainActivity.java
package com.example.mpulltofresh;

import java.util.ArrayList;
import java.util.List;

import com.example.mpulltofresh.RefreshListView.OnRefreshListener;

import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class RefreshMainActivity extends Activity {

	private List<String> textList;
	private MyAdapter adapter;
	private RefreshListView rListView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_listview_refresh_mani);
		// 获取listview
		rListView = (RefreshListView) findViewById(R.id.refresh_listview);
		// 获取数据
		textList = new ArrayList<String>();
		for (int i = 0; i < 25; i++) {
			textList.add("这是一条ListView的数据" + i);
		}
		// 创建设置适配器
		adapter = new MyAdapter();
		rListView.setAdapter(adapter);
		// 为listview添加事件监听(对listview的触控操作)

		rListView.setOnRefreshListener(new OnRefreshListener() {

			@Override
			public void onLoadingMore() {
				// TODO Auto-generated method stub

				new AsyncTask<Void, Void, Void>() {

					@Override
					protected Void doInBackground(Void... params) {
						SystemClock.sleep(5000);

						textList.add("这是加载更多出来的数据1");
						textList.add("这是加载更多出来的数据2");
						textList.add("这是加载更多出来的数据3");
						return null;
					}

					@Override
					protected void onPostExecute(Void result) {
						adapter.notifyDataSetChanged();

						// 控制脚布局隐藏
						rListView.hideFooterView();
					}
				}.execute(new Void[] {});

			}

			@Override
			public void onDownPullRefresh() {
				// TODO Auto-generated method stub

				new AsyncTask<Void, Void, Void>() {

					@Override
					protected Void doInBackground(Void... params) {
						SystemClock.sleep(2000);
						for (int i = 0; i < 2; i++) {
							textList.add(0, "这是下拉刷新出来的数据" + i);
						}
						return null;
					}

					@Override
					protected void onPostExecute(Void result) {
						adapter.notifyDataSetChanged();
						// 隐藏头布局
						rListView.hideHeaderView();
					}
				}.execute(new Void[] {});

			}
		});
	}

	private class MyAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return textList.size();
		}

		@Override
		public Object getItem(int position) {
			return textList.get(position);
		}

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

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			TextView textView = new TextView(RefreshMainActivity.this);
			textView.setText(textList.get(position));
			textView.setTextColor(Color.BLACK);
			textView.setTextSize(18.0f);
			return textView;
		}

	}
}

RefreshListView.java
package com.example.mpulltofresh;

import java.text.SimpleDateFormat;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class RefreshListView extends ListView implements OnScrollListener {

  private int firstVisibleItemPosition; // 屏幕显示在第一个的item的索引
  private int downY; // 按下时y轴的偏移量
  private OnRefreshListener mOnRefershListener;
  private boolean isScrollToBottom; // 是否滑动到底部
  private boolean isLoadingMore = false; // 是否正在加载更多中
  
  private int headerViewHeight; // 头布局的高度
  private View headerView; // 头布局的对象
  private View footerView; // 脚布局的对象
  private int footerViewHeight; // 脚布局的高度
  
  private final int DOWN_PULL_REFRESH = 0; // 下拉刷新状态
  private final int RELEASE_REFRESH = 1; // 松开刷新
  private final int REFRESHING = 2; // 正在刷新中
  private int currentState = DOWN_PULL_REFRESH; // 头布局的状态: 默认为下拉刷新状态

  private Animation upAnimation; // 向上旋转的动画
  private Animation downAnimation; // 向下旋转的动画

  private ImageView ivArrow; // 头布局的剪头
  private ProgressBar mProgressBar; // 头布局的进度条
  private TextView tvState; // 头布局的状态
  private TextView tvLastUpdateTime; // 头布局的最后更新时间

  /**
   * 当滚动状态改变时回调
   */
  @Override
  public void onScrollStateChanged(AbsListView view, int scrollState) {

	//没有滑动、按住
    if (scrollState == SCROLL_STATE_IDLE
        || scrollState == SCROLL_STATE_FLING) {
      // 判断当前是否已经到了底部
      if (isScrollToBottom && !isLoadingMore) {
        isLoadingMore = true;
        // 当前到底部
        footerView.setPadding(0, 0, 0, 0);
        this.setSelection(this.getCount());

        if (mOnRefershListener != null) {
          mOnRefershListener.onLoadingMore();
        }
      }
    }
  }
  /**
   * 当滚动时调用
   * 
   * @param firstVisibleItem
   *            当前屏幕显示在顶部的item的position
   * @param visibleItemCount
   *            当前屏幕显示了多少个条目的总数
   * @param totalItemCount
   *            ListView的总条目的总数
   */
  @Override
  public void onScroll(AbsListView view, int firstVisibleItem,
      int visibleItemCount, int totalItemCount) {
    firstVisibleItemPosition = firstVisibleItem;

    if (getLastVisiblePosition() == (totalItemCount - 1)) {
      isScrollToBottom = true;
    } else {
      isScrollToBottom = false;
    }
  }
  

  public RefreshListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initHeaderView();
    initFooterView();
    this.setOnScrollListener(this);
  }

  /**
   * 初始化脚布局
   */
  private void initFooterView() {
    footerView = View.inflate(getContext(), R.layout.activity_listview_refresh_footer, null);
    footerView.measure(0, 0);
    footerViewHeight = footerView.getMeasuredHeight();
    footerView.setPadding(0, -footerViewHeight, 0, 0);
    this.addFooterView(footerView);
  }

  /**
   * 初始化头布局
   */
  private void initHeaderView() {
    headerView = View.inflate(getContext(), R.layout.activity_listview_refresh_header, null);
    ivArrow = (ImageView) headerView
        .findViewById(R.id.iv_listview_header_down_arrow);
    mProgressBar = (ProgressBar) headerView
        .findViewById(R.id.pb_listview_header_progress);
    tvState = (TextView) headerView
        .findViewById(R.id.tv_listview_header_state);
    tvLastUpdateTime = (TextView) headerView
        .findViewById(R.id.tv_listview_header_last_update_time);

    // 设置最后刷新时间
    tvLastUpdateTime.setText("最后刷新时间: " + getLastUpdateTime());

    headerView.measure(0, 0); // 系统会帮我们测量出headerView的高度
    headerViewHeight = headerView.getMeasuredHeight();
    headerView.setPadding(0, -headerViewHeight, 0, 0);
    this.addHeaderView(headerView); // 向ListView的顶部添加一个view对象
    initAnimation();
  }

  /**
   * 获得系统的最新时间
   * 
   * @return
   */
  private String getLastUpdateTime() {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return sdf.format(System.currentTimeMillis());
  }

  /**
   * 初始化动画
   */
  private void initAnimation() {
    upAnimation = new RotateAnimation(0f, -180f,
        Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
        0.5f);
    upAnimation.setDuration(500);
    upAnimation.setFillAfter(true); // 动画结束后, 停留在结束的位置上

    downAnimation = new RotateAnimation(-180f, -360f,
        Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
        0.5f);
    downAnimation.setDuration(500);
    downAnimation.setFillAfter(true); // 动画结束后, 停留在结束的位置上
  }

  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN :
        downY = (int) ev.getY();
        break;
      case MotionEvent.ACTION_MOVE :
        int moveY = (int) ev.getY();
        // 移动中的y - 按下的y = 间距.
        int diff = moveY - downY;
        // -头布局的高度 + 间距 = paddingTop
        int paddingTop = -headerViewHeight + diff;
        // 如果: -头布局的高度 > paddingTop的值 执行super.onTouchEvent(ev);
        if (firstVisibleItemPosition == 0
            && -headerViewHeight < paddingTop) {
          if (paddingTop > 0 && currentState == DOWN_PULL_REFRESH) { // 完全显示了.
            currentState = RELEASE_REFRESH;
            refreshHeaderView();
          } else if (paddingTop < 0
              && currentState == RELEASE_REFRESH) { // 没有显示完全
            currentState = DOWN_PULL_REFRESH;
            refreshHeaderView();
          }
          // 下拉头布局
          headerView.setPadding(0, paddingTop, 0, 0);
          return true;
        }
        break;
      case MotionEvent.ACTION_UP :
        // 判断当前的状态是松开刷新还是下拉刷新
        if (currentState == RELEASE_REFRESH) {
          // 把头布局设置为完全显示状态
          headerView.setPadding(0, 0, 0, 0);
          // 进入到正在刷新中状态
          currentState = REFRESHING;
          refreshHeaderView();

          if (mOnRefershListener != null) {
            mOnRefershListener.onDownPullRefresh(); // 调用使用者的监听方法
          }
        } else if (currentState == DOWN_PULL_REFRESH) {
          // 隐藏头布局
          headerView.setPadding(0, -headerViewHeight, 0, 0);
        }
        break;
      default :
        break;
    }
    return super.onTouchEvent(ev);
  }

  /**
   * 根据currentState刷新头布局的状态
   */
  private void refreshHeaderView() {
    switch (currentState) {
      case DOWN_PULL_REFRESH : // 下拉刷新状态
        tvState.setText("下拉刷新");
        ivArrow.startAnimation(downAnimation); // 执行向下旋转
        break;
      case RELEASE_REFRESH : // 松开刷新状态
        tvState.setText("松开刷新");
        ivArrow.startAnimation(upAnimation); // 执行向上旋转
        break;
      case REFRESHING : // 正在刷新中状态
        ivArrow.clearAnimation();
        ivArrow.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.VISIBLE);
        tvState.setText("正在刷新中...");
        break;
      default :
        break;
    }
  }



  /**
   * 设置刷新监听事件
   * 
   * @param listener
   */
  public void setOnRefreshListener(OnRefreshListener listener) {
    mOnRefershListener = listener;
  }

  /**
   * 隐藏头布局
   */
  public void hideHeaderView() {
    headerView.setPadding(0, -headerViewHeight, 0, 0);
    ivArrow.setVisibility(View.VISIBLE);
    mProgressBar.setVisibility(View.GONE);
    tvState.setText("下拉刷新");
    tvLastUpdateTime.setText("最后刷新时间: " + getLastUpdateTime());
    currentState = DOWN_PULL_REFRESH;
  }

  /**
   * 隐藏脚布局
   */
  public void hideFooterView() {
    footerView.setPadding(0, -footerViewHeight, 0, 0);
    isLoadingMore = false;
  }
  
  
  public interface OnRefreshListener {

	  /**
	   * 下拉刷新
	   */
	  void onDownPullRefresh();

	  /**
	   * 上拉加载更多
	   */
	  void onLoadingMore();
	}
}



你可能感兴趣的:(PullToRefreshListView进阶(三)----->上拉加载、下拉刷新!)