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.AbsListView; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.AbsListView.OnScrollListener; public class MyListView extends ListView implements OnScrollListener{ 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 int footHeight; private View foot; private boolean footstate=false;//当前是否正在处于加载更多 // 旋转动画 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) { setOnScrollListener(this); // 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); initFoot(); initHeadRotateAnimation(); } //加载底部布局 private void initFoot() { foot = View.inflate(getContext(), R.layout.foot, null); addFooterView(foot); foot.measure(0, 0); footHeight = foot.getMeasuredHeight(); foot.setPadding(0, 0, 0,-footHeight); } 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(); void setDownRfe(); } @Override public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void onScrollStateChanged(AbsListView arg0, int state) { if(state==OnScrollListener.SCROLL_STATE_IDLE && getLastVisiblePosition()==(getCount()-1)&&footstate==false){ foot.setPadding(0, 0, 0, 0); setSelection(getCount()); footstate = true; if(listener!=null){ listener.setDownRfe(); } } } public void completeDown(){ footstate=false; foot.setPadding(0, 0, 0,-footHeight); } }
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) { switch (msg.what) { case 0: sa.notifyDataSetChanged(); lv.completeRef(); break; case 1: lv.completeDown(); break; default: break; } }; }; @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); } @Override public void setDownRfe() { for (int i = 0; i < 2; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("key1","下拉更新的数据"+i); map.put("key2","hehedaheheda"); list.add(list.size(), map); } handler.sendEmptyMessageDelayed(1,3000); } }); } }
<?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:orientation="horizontal" android:gravity="center"> <ProgressBar android:id="@+id/foot_pb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="20dp" /> <TextView android:id="@+id/foot_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加载更多..." android:textSize="20sp" android:textStyle="bold"/> </LinearLayout>