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

ListView下拉刷新(PullToRefresh)

2015-12-29 15:39 561 查看
1、首先准备一个ListView;(代码不粘)

2、设置下拉是出现的头部布局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="match_parent"
android:orientation="vertical" >

<!-- 下拉时,显示的背面布局 -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dip"
android:paddingTop="10dip" >

<LinearLayout
android:id="@+id/layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical" >

<!-- 下拉刷新文字提示部分 -->
<TextView
android:id="@+id/tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉可以刷新!" />

<TextView
android:id="@+id/lastUpdate_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

<!-- 箭头 -->
<ImageView
android:id="@+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dip"
android:layout_toLeftOf="@id/layout"
android:src="@drawable/pull_to_refresh_arrow" />

<!-- 进度条默认不显示,只有加载更多的时候才显示 -->
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20dip"
android:layout_toLeftOf="@id/layout"
android:visibility="gone" />
</RelativeLayout>

</LinearLayout>

3、新建类RefreshListView类:

package com.example.pulltorefresh;

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

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
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 {

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

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

public RefreshListView(Context context) {
super(context);
initView(context);
// TODO Auto-generated constructor stub
}

View header; // 顶部布局文件
int headerHeight; // 顶部布局文件的高度

// 初始化界面,添加顶部布局文件到ListView
private void initView(Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
header = inflater.inflate(R.layout.header, null);

measureView(header);// 通知父布局,占用的宽和高

headerHeight = header.getMeasuredHeight();
// Log.i("headerHeight", "headerHeight"+headerHeight);
topPadding(-headerHeight); // 传入的是高度值的负值,隐藏顶部布局
this.addHeaderView(header); // “添加”顶部布局文件

this.setOnScrollListener(this); // 设置滚动的监听事件
}

// 设置header布局上边距
private void topPadding(int topPadding) {
header.setPadding(header.getPaddingLeft(), topPadding,
header.getPaddingRight(), header.getPaddingBottom());
header.invalidate();
}

// 通知父布局,占用的宽和高
private void measureView(View view) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}

int width = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
int height;
int tempHeight = lp.height;
if (tempHeight > 0) {
height = MeasureSpec.makeMeasureSpec(tempHeight,
MeasureSpec.EXACTLY);
} else {
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}

view.measure(width, height);
}

int curScrollState;// 当前滚动状态

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
this.curScrollState = scrollState;
}

int firstVisibleItem;// 当前界面第一个可见的item的位置;
boolean isRemark;// 标记当前是在ListView最顶端摁下的;
int startY;// 开始Y值

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
this.firstVisibleItem = firstVisibleItem;// 通过判断firstVisibleItem,来判断是否在最顶端
}

IReflashListenter reflashListenter;
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (firstVisibleItem == 0) {
isRemark = true;
startY = (int) ev.getY();
}
break;

case MotionEvent.ACTION_MOVE:
onMove(ev);
break;
case MotionEvent.ACTION_UP:
if (state == RELESH) {
state = REFRESHING;

// 加载最新数据
reflashViewByState();

reflashListenter.onReflash();

} else if (state == PULL) {
state=NONE;
isRemark=false;
reflashViewByState();
}
break;

}

return super.onTouchEvent(ev);
}

// 判断移动过程中的操作
int state; // 当前状态
final int NONE = 0; // 正常状态
final int PULL = 1; // 提示下拉状态
final int RELESH = 2; // 提示松开释放状态
final int REFRESHING = 3; // 正在刷新状态

private void onMove(MotionEvent ev) {
// TODO Auto-generated method stub
if (!isRemark) {
return;
}
int tempY = (int) ev.getY();
int space = tempY - startY; // 记录拖动距离
int topPadding = space - headerHeight;
switch (state) {
case NONE:
if (space > 0) {
state = PULL;
}
reflashViewByState();
break;

case PULL:
topPadding(topPadding);
if (space > headerHeight + 30
&& curScrollState == SCROLL_STATE_TOUCH_SCROLL) {
state = RELESH;
reflashViewByState();
}
break;

case RELESH:
topPadding(topPadding);
if (space < headerHeight + 30) {
state = PULL;
reflashViewByState();
} else if (space <= 0) {
state = NONE;
isRemark = false;
reflashViewByState();
}
break;

}
}

// 根据当前状态改变界面显示
private void reflashViewByState() {
TextView tip = (TextView) header.findViewById(R.id.tip);
ImageView arrow = (ImageView) header.findViewById(R.id.arrow);
ProgressBar progress = (ProgressBar) header.findViewById(R.id.progress);

RotateAnimation animation1 = new RotateAnimation(0, 180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation1.setDuration(500);
animation1.setFillAfter(true);
RotateAnimation animation2 = new RotateAnimation(180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation1.setDuration(500);
animation1.setFillAfter(true);

switch (state) {
case NONE:
topPadding(-headerHeight);
arrow.clearAnimation();
break;

case PULL:
arrow.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
tip.setText("下拉可以刷新!");
arrow.clearAnimation();
arrow.setAnimation(animation2);
break;
case RELESH:
arrow.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
tip.setText("松开可以刷新!");
arrow.clearAnimation();
arrow.setAnimation(animation1);
break;
case REFRESHING:
topPadding(50);
arrow.setVisibility(View.GONE);
progress.setVisibility(View.VISIBLE);
arrow.clearAnimation();
tip.setText("正在刷新...");
break;
}
}

//获取完数据
public void reflashComplete(){
state = NONE;
isRemark = false;
reflashViewByState();
TextView lastupdatetime = (TextView) header
.findViewById(R.id.lastUpdate_time);
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
Date date = new Date(System.currentTimeMillis());
String time = format.format(date);
lastupdatetime.setText(time);
}

public void setInterface(IReflashListenter reflashListenter){
this.reflashListenter=reflashListenter;
}

//刷新数据接口
public interface IReflashListenter{
public void onReflash();
}
}
4、MainActivity:

package com.example.pulltorefresh;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SimpleAdapter;

import com.example.pulltorefresh.RefreshListView.IReflashListenter;

public class MainActivity extends Activity implements IReflashListenter, OnItemClickListener {
private RefreshListView listView;
private int NewsIcon[] = { R.drawable.tools1, R.drawable.tools2,
R.drawable.tools3, R.drawable.tools4, R.drawable.games1,
R.drawable.games2, R.drawable.games3, R.drawable.games4,
R.drawable.games5, R.drawable.games6 };
private String NewsName[] = { "ToolsItem1", "ToolsItem2", "ToolsItem3",
"ToolsItem4", "GamesItem1", "GamesItem2", "GamesItem3",
"GamesItem4", "GamesItem5", "GamesItem6" };
private SimpleAdapter adapter;
private List<Map<String, Object>> NewsDataList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

listView = (RefreshListView) findViewById(R.id.newsListView);
listView.setInterface(this);
NewsDataList = new ArrayList<Map<String, Object>>();
adapter = new SimpleAdapter(this, getNewsData(),
R.layout.news_tab_item,
new String[] { "NewsImage", "NewsName" }, new int[] {
R.id.newsImageViewItem, R.id.newssName });
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}

private List<? extends Map<String, ?>> getNewsData() {
// TODO Auto-generated method stub
for (int i = 0; i < NewsIcon.length; i++) {
Map<String, Object> GamesMap = new HashMap<String, Object>();
GamesMap.put("NewsImage", NewsIcon[i]);
GamesMap.put("NewsName", NewsName[i]);
NewsDataList.add(GamesMap);
}
return NewsDataList;
}

//获取刷新数据
private List<? extends Map<String, ?>> getReflashNewsData() {
// TODO Auto-generated method stub
for (int i = 0; i < 2; i++) {
Map<String, Object> GamesMap = new HashMap<String, Object>();
GamesMap.put("NewsImage", NewsIcon[i]);
GamesMap.put("NewsName", NewsName[i]+"刷新数据"+i);
NewsDataList.add(0,GamesMap);
}
return NewsDataList;
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// ListView的点击事件

}

@Override
public void onReflash() {
// TODO Auto-generated method stub
Handler handler=new Handler();
handler.postDelayed(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
//获取最新数据
getReflashNewsData();
//通知界面显示刷新数据
adapter = new SimpleAdapter(MainActivity.this, NewsDataList,
R.layout.news_tab_item,
new String[] { "NewsImage", "NewsName" }, new int[] {
R.id.newsImageViewItem, R.id.newssName }); //传入的是整个(新旧)NewsDataList
listView.setAdapter(adapter);
//通知ListView刷新数据完毕
listView.reflashComplete();
}
}, 2000);//此处是为了“表面上看上去有刷新延迟的效果”,实际应用中不需要

}

}
5、效果图:













完整代码:https://github.com/songshimvp/AndroidStudy/tree/master/PullToRefresh
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息