总的来说下拉刷新的功能实现较为简单,主要内容是对屏幕的一个滑动监听,并提供一个接口在适当的位置进行更新服务器数据。
在本项目中使用给ListView添加ListViewHeader的方式,添加一个View,并在开始时进行隐藏,在检测到向下滑动时,拉出View控件,并更新数据。
效果图;
下拉刷新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:padding="5dp"
android:orientation="horizontal" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
>
<ImageView
android:id="@+id/iv_reflash_arr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/common_listview_headview_red_arrow"
android:layout_gravity="center"
android:layout_marginTop="7dp"
/>
<ProgressBar
android:id="@+id/pb_reflash_ProgressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="58dp"
android:layout_height="58dp"
android:visibility="invisible"
android:indeterminateDrawable="@drawable/custom_progress"
android:layout_gravity="center" />
</FrameLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:orientation="vertical"
>
<TextView
android:id="@+id/tv_reflash_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉刷新"
android:textColor="@android:color/holo_red_light"
android:layout_gravity="center"
android:textSize="22sp"
/>
<TextView
android:id="@+id/tv_reflash_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2015-12-30 13:40:25"
android:layout_gravity="center"
android:layout_marginTop="7dp"
android:textColor="@android:color/darker_gray"
android:textSize="16sp"
/>
</LinearLayout>
</LinearLayout>
项目里介绍了一个非常好的结构方式,即自定义一个ListView:RefreshListView,并在内部进行相应配置。
package com.example.zhihuibj.view;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.example.zhihuibj.R;
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.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class RefreshListView extends ListView {
private static final int STATE_PULL_REFRESH=0;//下拉刷新
private static final int STATE_RELEASH_REFRESH=1;//松开刷新
private static final int STATE_REFRESHING=2;//正在刷新
private int mCurrentState=STATE_PULL_REFRESH;
private View mHeaderView;
private int mHeaderViewHeight;
private int startY=-1;
private TextView reflash_content;
private TextView reflash_data;
private ImageView reflash_arr;
private ProgressBar reflash_ProgressBar;
private RotateAnimation Animation_up;
private RotateAnimation Animation_down;
public RefreshListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
InitHeaderView();
}
public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
InitHeaderView();
}
public RefreshListView(Context context) {
super(context);
InitHeaderView();
}
/*
* 初始化头布局
*/
private void InitHeaderView() {
//实例化刷新列表
mHeaderView = View.inflate(getContext(), R.layout.reflash, null);
//添加一个头布局
this.addHeaderView(mHeaderView);
//默认隐藏下拉列表
mHeaderView.measure(0, 0);
mHeaderViewHeight = mHeaderView.getMeasuredHeight();
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
reflash_content =(TextView) mHeaderView.findViewById(R.id.tv_reflash_content);
reflash_data= (TextView)mHeaderView.findViewById(R.id.tv_reflash_date);
reflash_arr=(ImageView)mHeaderView.findViewById(R.id.iv_reflash_arr);
reflash_ProgressBar =(ProgressBar)mHeaderView.findViewById(R.id.pb_reflash_ProgressBar);
InitAnimation();
reflash_data.setText(GetCurrentTime());
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
//System.out.println("触摸屏幕!!!");
switch (ev.getAction()) {
/*
* 模拟器无法检测ACTION_DOWN事件
*/
case MotionEvent.ACTION_DOWN:
startY =(int) ev.getRawY();
// System.out.println("ACTION_DOWN : "+startY);
break;
/*
* 测量手指移动距离,并下移下拉列表
*/
case MotionEvent.ACTION_MOVE:
if(mCurrentState==STATE_REFRESHING)
break;
while(startY==-1)
{
startY =(int) ev.getRawY();//确保startY有效
}
int endY= (int)ev.getRawY(); //得到重点坐标
int dy = endY-startY;//移动偏移量
if(dy>0&&getFirstVisiblePosition()==0)//只有下拉并且是第一个item,才允许下拉
{
int padding=dy-mHeaderViewHeight;
mHeaderView.setPadding(0, padding, 0, 0);
if(padding>0&&mCurrentState!=STATE_RELEASH_REFRESH){//padding大于0,改为松开刷新
mCurrentState=STATE_RELEASH_REFRESH;
RefreshData(mCurrentState);
}
else if(padding<0&&mCurrentState!=STATE_PULL_REFRESH){//padding<0,改为下拉刷新
mCurrentState=STATE_PULL_REFRESH;
RefreshData(mCurrentState);
}
return true;
}
break;
case MotionEvent.ACTION_UP:
startY=-1;
if(mCurrentState==STATE_RELEASH_REFRESH)//松开刷新状态时,手指离开屏幕,进入正在刷新状态
{
mCurrentState=STATE_REFRESHING;
RefreshData(mCurrentState);
mHeaderView.setPadding(0, 0, 0, 0);
}
else if(mCurrentState==STATE_PULL_REFRESH)//下拉刷新时,松开手指,恢复原状态
{
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
}
break;
default:
break;
}
return super.onTouchEvent(ev);
}
private void RefreshData(int state) {
switch (state) {
case STATE_PULL_REFRESH:
reflash_content.setText("下拉刷新");
reflash_ProgressBar.setVisibility(View.INVISIBLE);
reflash_arr.setVisibility(View.VISIBLE);
reflash_arr.startAnimation(Animation_down);
break;
case STATE_RELEASH_REFRESH:
reflash_content.setText("松开刷新");
reflash_arr.clearAnimation();//切换下一个动画时,需要先清除动画
reflash_arr.startAnimation(Animation_up);
reflash_ProgressBar.setVisibility(View.INVISIBLE);
reflash_arr.setVisibility(View.VISIBLE);
break;
case STATE_REFRESHING:
reflash_content.setText("正在刷新...");
reflash_ProgressBar.setVisibility(View.VISIBLE);
reflash_arr.clearAnimation();//隐藏箭头图标时,需要先清除动画
reflash_arr.setVisibility(View.INVISIBLE);
if(mListener!=null)
mListener.onRefresh();
break;
default:
break;
}
}
public void setOnRefreshListener(OnRefreshListener listener)
{
mListener=listener;
}
public interface OnRefreshListener{
public void onRefresh();
}
OnRefreshListener mListener;
/*
* 收起下拉刷新控件
*/
public void onRefreshComplete(boolean success){
mCurrentState=STATE_PULL_REFRESH;
reflash_content.setText("下拉刷新");
reflash_ProgressBar.setVisibility(View.INVISIBLE);
reflash_arr.setVisibility(View.VISIBLE);
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
if(success)
reflash_data.setText(GetCurrentTime());
}
/*
* 获取当前时间
*/
public String GetCurrentTime()
{
SimpleDateFormat Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return Format.format(new Date());
}
/*
* 箭头动画
*/
public void InitAnimation(){
Animation_up=new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
Animation_up.setDuration(100);
Animation_up.setFillAfter(true);
Animation_down=new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
Animation_down.setDuration(100);
Animation_down.setFillAfter(true);
}
}
ontouchEvent :实现了对屏幕滑动的监听
View.measure:实现了对控件大小的测量
View.padding:实现了对下拉刷新View的位置控制
需要注意到的是;
public void setOnRefreshListener(OnRefreshListener listener)
{
mListener=listener;
}
public interface OnRefreshListener{
public void onRefresh();
}
OnRefreshListener mListener;
//设置下拉刷新监听
lv_tablist.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
TabDetailPagerGetDataFromService();
}
});
经过上面即实现了下拉刷新的功能。