ListView下拉刷新实现方式分析
1、需要添加顶部下拉加载界面;
2、我们需要监听onScrollListener,来判断当前是否显示在listview的最顶部;
3、因为顶部下拉加载界面是跟随收拾滑动状态不断改变界面显示的所以我们需要监听onTouch事件,来改变当前状态以及界面显示;
4、根据当前状态加载数据;
注:布局中的listview要改成重写的那个ListView
重写ListView
package com.example.listviewpager;
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;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ReFlashListView extends ListView implements OnScrollListener {
public View header;
private int headerHeight;
int firstVisibleItem;
boolean isRemark;
int startY;
int state;
final int NONE=0;//正常状态
final int PULL=1;//下拉状态
final int RELEASE=2;//提示释放状态
final int REFLASHING=3;//刷新状态
int scrollState;
IReflashListener iReflashListener;
public ReFlashListView(Context context) {
super(context);
initView(context);
}
public ReFlashListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public ReFlashListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
public void TopPadding(int topPadding){
header.setPadding(header.getPaddingLeft(), topPadding, header.getPaddingRight(), header.getPaddingBottom());
header.invalidate();
}
public void MeasureView(View view){
ViewGroup.LayoutParams p=view.getLayoutParams();
if(p==null){
p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
int width;
width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
int height;
int tempHeight = p.height;
if(tempHeight>0){
height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);
}else{
height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
view.measure(width,height);
}
public void initView(Context context){
LayoutInflater inflater = LayoutInflater.from(context);
header=inflater.inflate(R.layout.header_layout,null);
MeasureView(header);
headerHeight=header.getMeasuredHeight();
TopPadding(-headerHeight);
this.addHeaderView(header);
this.setOnScrollListener(this);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.scrollState=scrollState;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.firstVisibleItem=firstVisibleItem;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
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==RELEASE){
state=REFLASHING;
reflashViewByState();
iReflashListener.onReflash();
}else if(state==PULL){
state = NONE;
isRemark=false;
reflashViewByState();
}
break;
}
return super.onTouchEvent(ev);
}
private void onMove(MotionEvent ev){
if(!isRemark){
return;
}else{
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&&scrollState==SCROLL_STATE_TOUCH_SCROLL){
state=RELEASE;
reflashViewByState();
}
break;
case RELEASE:
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) findViewById(R.id.tip);
ImageView jiantou = (ImageView) findViewById(R.id.arrow);
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress);
RotateAnimation anim = new RotateAnimation(0, 180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(500);
anim.setFillAfter(true);
RotateAnimation anim1 = new RotateAnimation(180,0, RotateAnimation.RELATIVE_TO_SELF,0.5f, RotateAnimation.RELATIVE_TO_SELF,0.5f);
anim1.setDuration(500);
anim1.setFillAfter(true);
switch (state){
case NONE:
TopPadding(-headerHeight);
break;
case PULL:
jiantou.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
tip.setText("下拉可以刷新");
jiantou.clearAnimation();
jiantou.setAnimation(anim1);
break;
case RELEASE:
jiantou.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
tip.setText("松开可以刷新");
jiantou.clearAnimation();
jiantou.setAnimation(anim);
break;
case REFLASHING:
TopPadding(50);
jiantou.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
tip.setText("正在刷新...");
jiantou.clearAnimation();
break;
}
}
public void reflashComplete(){
state = NONE;
isRemark = false;
reflashViewByState();
TextView lastUpdateTime = (TextView) findViewById(R.id.refresh_time);
SimpleDateFormat format = new SimpleDateFormat("yyy年MM月DD日 hh:mm:ss");
Date date = new Date(System.currentTimeMillis());
String time = format.format(date);
lastUpdateTime.setText(time);
}
public void setInterface(IReflashListener iReflashListener){
this.iReflashListener = iReflashListener;
}
public interface IReflashListener{
public void onReflash();
}
}
主Activity
package com.example.listviewpager;
import android.app.Activity;
import android.os.Bundle;
import android.widget.SimpleAdapter;
import com.example.listviewpager.ReFlashListView.IReflashListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends Activity implements IReflashListener{
public SimpleAdapter simpleAdapter;
private List<Map<String, Object>> listData;
private List<Map<String, Object>> listData2;
ReFlashListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ReFlashListView) findViewById(R.id.listview);
listView.setInterface(this);
listData = new ArrayList<Map<String,Object>>();
listData2 = new ArrayList<Map<String,Object>>();
simpleAdapter = new SimpleAdapter(this, getData(), R.layout.item, new String[]{"iv", "tv1", "tv2","bt"}, new int[]{R.id.iv, R.id.tv1, R.id.tv2,R.id.bt});
listView.setAdapter(simpleAdapter);
}
public List<Map<String, Object>> getData() {
for (int i = 0; i < 30; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("iv", R.mipmap.ic_launcher);
map.put("tv1", "嘻嘻");
map.put("tv2", "哈哈");
map.put("bt", "安装");
listData.add(map);
}
return listData;
}
public List<Map<String, Object>> getReflashData() {
for (int i = 0; i < 30; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("iv", R.mipmap.ic_launcher);
map.put("tv1", "嘻嘻");
map.put("tv2", "哈哈");
map.put("bt", "安装");
listData2.add(map);
}
return listData2;
}
@Override
public void onReflash() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
simpleAdapter = new SimpleAdapter(this, getReflashData(), R.layout.item, new String[]{"iv", "tv1", "tv2","bt"}, new int[]{R.id.iv, R.id.tv1, R.id.tv2,R.id.bt});
listView.setAdapter(simpleAdapter);
listView.reflashComplete();
}
}
ListView的底部上拉加载更多
实现方式和下拉刷新类似:
加载类:
public void initView(Context context){
LayoutInflater inflater = LayoutInflater.from(context);
header=inflater.inflate(R.layout.header_layout,null);
footer = inflater.inflate(R.layout.foot, null);
footer.findViewById(R.id.load_layout).setVisibility(GONE);
this.addFooterView(footer);
MeasureView(header);
headerHeight=header.getMeasuredHeight();
TopPadding(-headerHeight);
this.addHeaderView(header);
this.setOnScrollListener(this);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
this.scrollState=scrollState;
if(lastItemCount==totalItemCount&&scrollState==SCROLL_STATE_IDLE){
if(!isLoading) {
isLoading=true;
footer.findViewById(R.id.load_layout).setVisibility(VISIBLE);
iLoadListener.onLoad();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.firstVisibleItem=firstVisibleItem;
this.lastItemCount = firstVisibleItem + visibleItemCount; //最后一个item等于第一个+可见的item
this.totalItemCount = totalItemCount;
public void loadComplete(){
isLoading=false;
footer.findViewById(R.id.load_layout).setVisibility(GONE);
}
public void setInterfaceLoad(ILoadListener iLoadListener){
this.iLoadListener = iLoadListener;
}
public interface ILoadListener{
public void onLoad();
}
主Activity:
listView.setInterfaceLoad(this);
public void onLoad() {
simpleAdapter = new SimpleAdapter(this, getLoadData(), R.layout.item, new String[]{"iv", "tv1", "tv2","bt"}, new int[]{R.id.iv, R.id.tv1, R.id.tv2,R.id.bt});
listView.setAdapter(simpleAdapter);
listView.loadComplete();
}