首先要知道刷新有三個狀態,java
1是下拉中android
2是鬆開刷新app
3是正在刷新ide
還有一個很是重要的是回調接口,這個接口是正在刷新的時候外界須要作的事。佈局
而後外界再把狀態重置。動畫
回調接口須要三個屬性,this
private OnRefLisner listener;spa
public void setOnRefLisner(OnRefLisner listener){
this.listener = listener;
}code
//回調接口
public interface OnRefLisner{
void setPullRfe();
}orm
package com.example.listviewf5; import java.text.SimpleDateFormat; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.animation.RotateAnimation; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; public class MyListView extends ListView { private View v; private int headHeight;// 頭部的高度 private int downY;// 按下時候Y座標 private final int PULL_REF = 0;// 下拉 private final int REL_REF = 1;// 鬆開刷新 private final int REFING = 2;// 刷新中 private int currentState = PULL_REF; private TextView tv; private TextView tvtiem; private ImageView img; private ProgressBar pb; //旋轉動畫 private RotateAnimation upAnimation,downAnimation; public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub initView(context); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub initView(context); } public MyListView(Context context) { super(context); // TODO Auto-generated constructor stub initView(context); } /** * 加載頂部佈局文件 * * @param context */ private void initView(Context context) { // LayoutInflater in =LayoutInflater.from(context); // v = in.inflate(R.layout.head,null); v = View.inflate(context, R.layout.head, null); this.addHeaderView(v); v.measure(0, 0);// 通知系統測量寬高 headHeight = v.getMeasuredHeight();// 獲得測量後的高度 v.setPadding(0, -headHeight, 0, 0);// 進行隱藏head,就是把paddingtop設置成負高度 tv = (TextView) v.findViewById(R.id.head_tv); tvtiem = (TextView) v.findViewById(R.id.head_tvtime); img = (ImageView) v.findViewById(R.id.head_img); pb = (ProgressBar) v.findViewById(R.id.pb); initHeadRotateAnimation(); } private void initHeadRotateAnimation() { upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); upAnimation.setDuration(300); upAnimation.setFillAfter(true); downAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); downAnimation.setDuration(300); downAnimation.setFillAfter(true); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: downY = (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: //若是是正在刷新狀態滑動沒有 if(currentState==REFING){ break; } int deltaY = (int) (ev.getY() - downY);// 獲得移動的距離 int currentHeight = -headHeight + deltaY; // 判斷當前的距離是否是大於headHeight 而且顯示的是第一個位置 if (currentHeight > -headHeight && getFirstVisiblePosition() == 0) { v.setPadding(0, currentHeight, 0, 0);// 展示頭部 if (currentHeight >= 0 && currentState == PULL_REF) { currentState = REL_REF; refHeadView(); } else if (currentHeight < 0 && currentState == REL_REF) { currentState = PULL_REF; refHeadView(); } return true;// 攔截事件不讓listview處理 } break; case MotionEvent.ACTION_UP: //判斷當前是否是要刷新狀態 if(currentState==PULL_REF){ v.setPadding(0, -headHeight, 0, 0); }else if(currentState==REL_REF){ currentState=REFING; v.setPadding(0,0, 0, 0); refHeadView(); if(listener!=null){ listener.setPullRfe(); } } break; } return super.onTouchEvent(ev); } private void refHeadView() { switch (currentState) { case PULL_REF: tv.setText("下拉刷新"); img.startAnimation(downAnimation); break; case REL_REF: tv.setText("鬆開刷新"); img.startAnimation(upAnimation); break; case REFING: tv.setText("正在刷新……"); img.setVisibility(View.GONE); img.clearAnimation(); pb.setVisibility(View.VISIBLE); break; default: break; } } //刷新完成要把控件和狀態重置 public void completeRef(){ v.setPadding(0, -headHeight, 0, 0);// 展示頭部 currentState=PULL_REF; tv.setText("下拉刷新"); img.setVisibility(View.VISIBLE); pb.setVisibility(View.GONE); SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String date = sDateFormat.format(new java.util.Date()); tvtiem.setText("最後刷新:"+date); } private OnRefLisner listener; public void setOnRefLisner(OnRefLisner listener){ this.listener = listener; } //回調接口 public interface OnRefLisner{ void setPullRfe(); } }
package com.example.listviewf5; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.example.listviewf5.MyListView.OnRefLisner; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.view.Menu; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; public class MainActivity extends Activity { private MyListView lv; private List<Map<String, Object>> list; private SimpleAdapter sa; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { sa.notifyDataSetChanged(); lv.completeRef(); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv = (MyListView) findViewById(R.id.lv); list = new ArrayList<Map<String,Object>>(); for (int i = 0; i <20; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("key1","神馬都是浮雲"); map.put("key2","heheda"); list.add(map); } sa = new SimpleAdapter(this, list,R.layout.item_lv, new String[]{"key1","key2"},new int[]{R.id.tv,R.id.tv2}); lv.setAdapter(sa); lv.setOnRefLisner(new OnRefLisner() { @Override public void setPullRfe() { Map<String, Object> map = new HashMap<String, Object>(); map.put("key1","下拉更新的數據"); map.put("key2","hehedaheheda"); list.add(0, map); handler.sendEmptyMessageDelayed(0,3000); } }); } }