您的位置:首页 > 其它

下拉刷新ListView讲解,自定义PullToRefreshListView

2016-04-08 18:54 441 查看

思路

关于下拉刷新的ListView的实现,思路主要有两种:

1 . 用LinearLayout包裹一个refreshHeadView和一个listView , 触摸时通过改变refreshHeadView的LayoutParams参数的 topMargin来隐藏和显示refreshHeadView,lp.topMargin = - refreshHeadHeight 时,头部隐藏,lp.topMargin = 0 时,头部恰好完全出现。我的另外一篇博客实现了这个思路 :

[ http://blog.csdn.net/u010335298/article/details/50956995 ]

2 . 用ListView的addHeaderView方法,为ListView设置一个headView作为下拉刷新的view ,通过设置headView的topPadding来显示和隐藏headView , topPadding = - headHeight的时候,headView隐藏,topPadding = 0 时 ,头部恰好完全出现 。这篇博客就是用这种思路实现的。

效果



流程

为了方便讲解,我画了图来描述我的实现思路。



代码

下面是激动人心的代码啦~

package com.example.myapp.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.Scroller;
import android.widget.TextView;

import com.example.myapp.R;

/**
* Created by zyr
* DATE: 16-4-6
* Time: 下午4:02
* Email: yanru.zhang@renren-inc.com
*
* 通过listview addHeaderView来实现下拉刷新
*/
public class CustomPullToRefreshListView2 extends ListView implements AbsListView.OnScrollListener {
private Context mContext;

private View headerView;

private TextView headerTv;

private int headerHeight;

private Scroller mScroller;

public static final int STATE_NONE  = 0;
public static final int STATE_PULL_TO_REFRESH = 1; //下拉去刷新
public static final int STATE_RELEASE_TO_REFRESH = 2; // 释放进行刷新
public static final int STATE_REFRESHING = 3; // 正在刷新

private int state = STATE_NONE;
private int downY;

public static final int DURATION = 500;
private OnRefreshListener mOnRefreshListener;

public interface OnRefreshListener{
void onDownPullRefresh();
}

/************************   构造****************************************/

public CustomPullToRefreshListView2(Context context) {
this(context, null);
}

public CustomPullToRefreshListView2(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public CustomPullToRefreshListView2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;

initScroller();
initHeaderView();
setOnScrollListener(this);
}

private void initScroller() {
mScroller = new Scroller(getContext(), new DecelerateInterpolator());
}

@Override
public void computeScroll() {
super.computeScroll();
if(mScroller.computeScrollOffset()){
headerView.setPadding(0, mScroller.getCurrY(), 0, 0);
}
}

private void initHeaderView() {
headerView =  View.inflate(getContext(), R.layout.header_listview, null);
headerTv = (TextView) headerView.findViewById(R.id.tvHead);
headerView.measure(0, 0); // 系统会帮我们测量出headerView的高度
headerHeight = headerView.getMeasuredHeight();
Log.d("zyr", "--------------------headerHeight :" + headerHeight);
headerView.setPadding(0, -headerHeight, 0, 0);
invalidate();
Log.d("zyr", "----------------------headerPaddingTop :" + headerView.getPaddingTop());
super.addHeaderView(headerView, null, false);
}

/**************************     Scroll******************************/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}

/***************************    Touch***************************************/
@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) / 2;
// -头布局的高度 + 间距 = paddingTop
int paddingTop = -headerHeight + diff;
// 如果: 第一个可见,向下拉
if (getFirstVisiblePosition() == 0
&&  diff > 0) {
if (paddingTop > 0 ) { // 完全显示了.
Log.i("zyr", "松开刷新");
state = STATE_RELEASE_TO_REFRESH;
refreshHeaderView();
} else if (paddingTop < 0 ) { // 没有显示完全
Log.i("zyr", "下拉刷新");
state = STATE_PULL_TO_REFRESH;
refreshHeaderView();
}
// 下拉头布局
Log.d("zyr","--------------paddingTop:" + paddingTop);
headerView.setPadding(0, paddingTop, 0, 0);
return true;
}
break;
case MotionEvent.ACTION_UP :
// 判断当前的状态是松开刷新还是下拉刷新
if (state == STATE_RELEASE_TO_REFRESH) {
Log.i("zyr", "刷新数据.");
// 把头布局设置为完全显示状态
mScroller.startScroll(0,headerView.getPaddingTop(),0,0-headerView.getPaddingTop(),DURATION);
postInvalidate();
// 进入到正在刷新中状态
state = STATE_REFRESHING;
refreshHeaderView();

if (mOnRefreshListener != null) {
mOnRefreshListener.onDownPullRefresh(); // 调用使用者的监听方法
}
} else if (state == STATE_PULL_TO_REFRESH) {
// 隐藏头布局
mScroller.startScroll(0,headerView.getPaddingTop(),0,- headerHeight -headerView.getPaddingTop(),DURATION);
postInvalidate();
}
break;
default :
break;
}
return super.onTouchEvent(ev);
}
/**
* 根据currentState刷新头布局的状态
*/
private void refreshHeaderView() {
switch (state) {
case STATE_PULL_TO_REFRESH : // 下拉刷新状态
headerTv.setText("下拉刷新");
break;
case STATE_RELEASE_TO_REFRESH : // 松开刷新状态
headerTv.setText("松开刷新");
break;
case STATE_REFRESHING : // 正在刷新中状态
headerTv.setText("正在刷新中...");
break;
default :
break;
}
}

/**
* 隐藏头布局
*/
public void hideHeaderView() {
post(new Runnable() {
@Override
public void run() {
mScroller.startScroll(0,headerView.getPaddingTop(),0,- headerHeight -headerView.getPaddingTop(),DURATION);
postInvalidate();
headerTv.setText("下拉刷新");
state = STATE_NONE;
}
});
}

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

}


header_listiew.xml

<?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"
android:orientation="vertical">

<!-- 内容 -->

<RelativeLayout
android:id="@+id/head_contentLayout"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:gravity="center">
<TextView
android:id="@+id/tvHead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pull_to_refresh_pull_label"
android:textColor="@color/black"
android:textSize="15.5sp"
android:textStyle="bold" />
</RelativeLayout>

</LinearLayout>


activity调用

listView = (CustomPullToRefreshListView2) findViewById(R.id.listview);
for(int i=0;i<20;i++){
strings.add("zyr" + i);
}
commonAdapter = new CommonAdapter(this,strings);
listView.setAdapter(commonAdapter);
listView.setOnRefreshListener(new CustomPullToRefreshListView2.OnRefreshListener() {
@Override
public void onDownPullRefresh() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
listView.hideHeaderView();
}
}).start();
}
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  listview