您的位置:首页 > 移动开发 > Android开发

Android下拉加载,上拉刷新的实现

2016-01-18 15:10 591 查看
曾经一度,自己因为实现此功能也是在看了各种网络资料,最终得以实现。今天闲来无事,就贴出代码,供像曾经的我一样的童鞋们参考参考

。话不多说贴代码了

自定义的RefreshListView

package com.zyd.pullupandrefresh.view;

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

import com.zyd.pullupandrefresh.R;

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

/**
* @author YadiZheng
*
*/
public class RefreshListView extends ListView implements OnScrollListener {

private View headView;
private int height;
private int downY;

private final int PULL_REFRESH = 0;// 下拉刷新
private final int REALEASE_REFRESH = 1;// 松开刷新
private final int REFRESHING = 2;// 正在刷新
private int currentState = PULL_REFRESH;// 当前状态
// 初始化布局
private ImageView iv_arrow;
private ProgressBar bar_rotate;
private TextView timeTv, stateTv;
// 定义旋转动画
private RotateAnimation up, down;
// 当前是否在加载
private boolean isLoading = false;

public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}

private void init() {
// 设置滚动监听器
setOnScrollListener(this);
initRotateAnimation();
initHeadView();
initFootView();
}

/**
* 初始化旋转动画
* */
private void initRotateAnimation() {
// 向上旋转
up = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF,
0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
// 动画持续的时间
up.setDuration(300);// 300ms
up.setFillAfter(true);
// 向下旋转
down = new RotateAnimation(-180, -360,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
down.setDuration(300);// 300ms
down.setFillAfter(true);
}

private void initHeadView() {
headView = View.inflate(getContext(), R.layout.head, null);

iv_arrow = (ImageView) headView.findViewById(R.id.iv_arrow);
bar_rotate = (ProgressBar) headView.findViewById(R.id.bar_rotate);
timeTv = (TextView) headView.findViewById(R.id.tv_time);
stateTv = (TextView) headView.findViewById(R.id.tv_state);

headView.measure(0, 0);
height = headView.getMeasuredHeight();
headView.setPadding(0, -height, 0, 0);
addHeaderView(headView);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (int) ev.getY();
break;

case MotionEvent.ACTION_MOVE:
int deltaY = (int) (ev.getY() - downY);
int paddingTop = -height + deltaY;
// 当课件条目是0的时候才可以下拉刷新
if (paddingTop > -height && getFirstVisiblePosition() == 0) {
headView.setPadding(0, paddingTop, 0, 0);
if (paddingTop >= 0 && currentState == PULL_REFRESH) {
// 从下拉刷新进入松开刷新状态
currentState = REALEASE_REFRESH;
refreshHeadView();
} else if (paddingTop <= 0 && currentState == REALEASE_REFRESH) {
// 进入下拉刷新状态
currentState = PULL_REFRESH;
refreshHeadView();
}

return true;// 拦截TouchMove,不然ListView处理该事件,会造成ListView无法滑动
}
break;
case MotionEvent.ACTION_UP:
if (currentState == PULL_REFRESH) {
headView.setPadding(0, -height, 0, 0);
} else if (currentState == REALEASE_REFRESH) {
// headView完全显示
headView.setPadding(0, 0, 0, 0);
currentState = REFRESHING;
refreshHeadView();

if (listener != null) {
listener.onPullRefresh();
}
}
break;
}
return super.onTouchEvent(ev);
}

/**
* 根据currentState来更新headView
*/
private void refreshHeadView() {
switch (currentState) {
case PULL_REFRESH:
stateTv.setText("下拉刷新");
iv_arrow.startAnimation(down);
break;
case REALEASE_REFRESH:
stateTv.setText("松开刷新");
iv_arrow.startAnimation(up);
break;
case REFRESHING:
// 停止动画
iv_arrow.clearAnimation();
// 隐藏箭头
iv_arrow.setVisibility(View.INVISIBLE);
// 显示bar_rotate
bar_rotate.setVisibility(View.VISIBLE);
stateTv.setText("正在刷新,请稍后");
break;
}
}

/**
* 完成刷新操作,重置状态
*/
public void completeRefresh() {
if (isLoading) {
// 重置footView
footView.setPadding(0, 0, 0, -footViewHeight);
isLoading = false;
} else {
// 重置headView
headView.setPadding(0, -height, 0, 0);
currentState = PULL_REFRESH;
bar_rotate.setVisibility(View.INVISIBLE);
iv_arrow.setVisibility(View.VISIBLE);
stateTv.setText("下拉刷新");
timeTv.setText("最后刷新:" + getCurrentTime());
}

}

/**
* 获取当前时间
*
* @return
*/
private String getCurrentTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date());
}

private OnRefreshListener listener;
private View footView;
private int footViewHeight;

public void setOnRefreshListener(OnRefreshListener listener) {
this.listener = listener;
}

public interface OnRefreshListener {
void onPullRefresh();

void onLoadingMore();
}

/**
* 初始化FootView
*/
private void initFootView() {
footView = View.inflate(getContext(), R.layout.bottom, null);
footView.measure(0, 0);
footViewHeight = footView.getMeasuredHeight();
// Log.e("footViewHeight","++++"+footViewHeight);
footView.setPadding(0, 0, 0, -footViewHeight);
addFooterView(footView);
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub

}

/**
* SCROLL_STATE_IDLE:闲置状态,就是手指松开 SCROLL_STATE_TOUCH_SCROLL:手指触摸滚动
* SCROLL_STATE_FLING:快速手指松开
*
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE
&& getLastVisiblePosition() == (getCount() - 1)) {
// Log.e("onScrollStateChanged","此时需要显示footView");
isLoading = true;
footView.setPadding(0, 0, 0, 0);
setSelection(getCount());// 显示ListView最后一条
if (listener != null) {
listener.onLoadingMore();
}
}

}

}


head.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="match_parent"
android:gravity="center_horizontal"
android:orientation="horizontal" >

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
>
<ImageView
android:id="@+id/iv_arrow"
android:layout_centerInParent="true"
android:background="@drawable/indicator_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ProgressBar
android:id="@+id/bar_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_centerInParent="true"
android:indeterminateDuration="1000"
android:visibility="invisible"
android:indeterminateDrawable="@drawable/rotate"
/>
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
>
<TextView
android:id="@+id/tv_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉刷新"
android:textColor="#aa000000"
android:textSize="18sp"
/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@android:color/darker_gray"
/>
</LinearLayout>

</LinearLayout>


bottom.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:gravity="center"
android:orientation="horizontal" >

<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:indeterminate="true"
android:indeterminateDrawable="@drawable/rotate"
android:indeterminateDuration="1000" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"
android:text="加载更多"
android:textColor="#aa000000"
android:textSize="20sp" />

</LinearLayout>

有需要源码的,请点击源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: