你的位置:首页 > 操作系统

[操作系统]ListView下拉刷新

下拉刷新-------
    1.addHeaderView必须在setAdapter之前调用
    2.将paddingTop设置一个headerView高度的负值去隐藏它
    
    getHeight()和getMeasuredHeight()的区别:
    getMeasuredHeight():获取测量完的高度,只要在onMeasure方法执行完,就可以用
                        它获取到宽高,在自定义控件内部多使用这个
                        使用view.measure(0,0)方法可以主动通知系统去测量,然后就
                        可以直接使用它获取宽高
    getHeight():必须在onLayout方法执行完后,才能获得宽高
                view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                    headerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    int headerViewHeight = headerView.getHeight();
                    //直接可以获取宽高
            }
        });
    3.setSelection(position);将对应位置的item放置到屏幕顶端

 

其中headerView的布局文件

<?  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:gravity="center_horizontal"  android:orientation="horizontal" >  <RelativeLayout    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginBottom="10dp"    android:layout_marginTop="10dp" >    <ImageView      android:id="@+id/iv_arrow"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:background="@drawable/indicator_arrow"      android:contentDescription="@null" />    <ProgressBar      android:id="@+id/pb_rotate"      android:layout_width="30dp"      android:layout_height="30dp"      android:visibility="invisible"      android:layout_centerInParent="true"      android:indeterminateDrawable="@drawable/indeterminate_drawable"      android:indeterminateDuration="2000" />  </RelativeLayout>  <LinearLayout    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginBottom="10dp"    android:layout_marginLeft="15dp"    android:layout_marginTop="10dp"    android:gravity="center"    android:orientation="vertical" >    <TextView      android:id="@+id/tv_state"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="下拉刷新"      android:textColor="#aa000000"      android:textSize="20sp" />    <TextView      android:id="@+id/tv_time"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="最后刷新:"      android:textColor="@android:color/darker_gray"      android:textSize="14sp" />  </LinearLayout></LinearLayout>

View Code

其中footerView的布局文件

<?  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:gravity="center"  android:orientation="horizontal" >  <ProgressBar    android:layout_width="30dp"    android:layout_height="30dp"    android:layout_marginTop="10dp"    android:layout_marginBottom="10dp"    android:indeterminate="true"    android:indeterminateDrawable="@drawable/indeterminate_drawable"    android:indeterminateDuration="1000" />  <TextView android:layout_width="wrap_content"    android:layout_marginTop="10dp"    android:layout_marginBottom="10dp"    android:layout_height="wrap_content"    android:textColor="#aa000000"    android:layout_marginLeft="15dp"    android:textSize="20sp"    android:text="加载更多..."/></LinearLayout>

View Code

android:indeterminateDrawable="@drawable/indeterminate_drawable"

<?   android:fromDegrees="0"  android:pivotX="50%"  android:pivotY="50%"  android:drawable="@drawable/indicate_rotate"  android:toDegrees="360">  </rotate>

RefreshListView的主代码

package com.demo.pullrefresh.view;import java.text.SimpleDateFormat;import java.util.Date;import com.demo.pullrefresh.R;import android.annotation.SuppressLint;import android.content.Context;import android.util.AttributeSet;import android.util.Log;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 RefreshListView extends ListView implements OnScrollListener {  private View headerView;// headerView  private ImageView iv_arrow;  private ProgressBar pb_rotate;  private TextView tv_state, tv_time;  private int downY;// 按下时y的坐标  private int headerViewHeight;// headerView高  private View footerView;  private int footerViewHeight;  private final int PULL_REFRESH = 0;// 下拉刷新的状态  private final int RELEASE_REFRESH = 1;// 松开刷新的状态  private final int REFRESHING = 2;// 正在刷新的状态  private int currentState = PULL_REFRESH;// headerView的默认位置  private RotateAnimation upAnimation, downAnimation;  private boolean isLoadingMore = false;// 当前是否正在处于加载更多  public RefreshListView(Context context) {    super(context);    init();  }  public RefreshListView(Context context, AttributeSet attrs) {    super(context, attrs);    init();  }  private void init() {    setOnScrollListener(this);    initHeaderView();    initFooterView();    initRotateAnimation();  }  /**   * 初始化headerView   */  private void initHeaderView() {    headerView = View.inflate(getContext(), R.layout.layout_header, null);    // headerView    // =LayoutInflater.from(getContext()).inflate(R.layout.layout_header,    // null);    iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow);    pb_rotate = (ProgressBar) headerView.findViewById(R.id.pb_rotate);    tv_state = (TextView) headerView.findViewById(R.id.tv_state);    tv_time = (TextView) headerView.findViewById(R.id.tv_time);    // 第一种方法    // headerView.getViewTreeObserver().addOnGlobalLayoutListener(new    // OnGlobalLayoutListener() {    // @Override    // public void onGlobalLayout() {    // headerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);    // int headerViewHeight = headerView.getHeight();    //    //    // Log.e("MainActivity", "headerViewHeight: "+headerViewHeight);    // headerView.setPadding(0, -headerViewHeight, 0, 0);    // refreshListView.addHeaderView(headerView);//    // }    // });    // 第二种方法    headerView.measure(0, 0);// 主动通知系统去测量    headerViewHeight = headerView.getMeasuredHeight();    Log.e("MainActivity", "headerViewHeight: " + headerViewHeight);    headerView.setPadding(0, -headerViewHeight, 0, 0);    addHeaderView(headerView);//  }  /**   * 初始化旋转动画   */  private void initRotateAnimation() {    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);  }  /**   * 初始化footerView   */  private void initFooterView() {    footerView = View.inflate(getContext(), R.layout.layout_footer, null);    footerView.measure(0, 0);// 主动通知系统去测量该View    footerViewHeight = footerView.getMeasuredHeight();    footerView.setPadding(0, -footerViewHeight, 0, 0);    addFooterView(footerView);  }  @Override  public boolean onTouchEvent(MotionEvent ev) {    switch (ev.getAction()) {    case MotionEvent.ACTION_DOWN:      downY = (int) ev.getY();      break;    case MotionEvent.ACTION_MOVE:      int deltaY = (int) (ev.getY() - downY);      int paddingTop = -headerViewHeight + deltaY;      if (paddingTop > -headerViewHeight          && getFirstVisiblePosition() == 0) {        headerView.setPadding(0, paddingTop, 0, 0);        Log.d("jiejie", "paddingtop" + paddingTop);        if (paddingTop >= 0 && currentState == PULL_REFRESH) {          // 从下拉刷新进入松开刷新的状态          currentState = RELEASE_REFRESH;          refreshHeaderView();        } else if (paddingTop < 0 && currentState == RELEASE_REFRESH) {          // 进入下拉刷新的状态          currentState = PULL_REFRESH;          refreshHeaderView();        }        return true;// 拦截TouchMove,不让ListView处理该次move事件,不过会造成ListView无法滑动      }      break;    case MotionEvent.ACTION_UP:      if (currentState == PULL_REFRESH) {        // 隐藏headerView        headerView.setPadding(0, -headerViewHeight, 0, 0);      } else if (currentState == RELEASE_REFRESH) {        headerView.setPadding(0, 0, 0, 0);        currentState = REFRESHING;        refreshHeaderView();        if (listener != null) {          listener.onPullRefersh();        }      }      break;    }    return super.onTouchEvent(ev);  }  /**   * 根据currentState来更新headerView   */  private void refreshHeaderView() {    switch (currentState) {    case PULL_REFRESH:      tv_state.setText("下拉刷新");      iv_arrow.startAnimation(downAnimation);      break;    case RELEASE_REFRESH:      tv_state.setText("松开刷新");      iv_arrow.startAnimation(upAnimation);      break;    case REFRESHING:      iv_arrow.clearAnimation();// 因为向上的旋转动画有可能没有执行完      iv_arrow.setVisibility(View.INVISIBLE);      pb_rotate.setVisibility(View.VISIBLE);      tv_state.setText("正在刷新...");      break;    }  }  /**   * 完成刷新操作,重置状态,在你获取完数据并更新完adater之后,去在UI线程中调用该方法   */  public void completeRefresh() {    if (isLoadingMore) {      // 重置footerView状态      footerView.setPadding(0, -footerViewHeight, 0, 0);      isLoadingMore = false;    } else {      // 重置headerView状态      headerView.setPadding(0, -headerViewHeight, 0, 0);      currentState = PULL_REFRESH;      pb_rotate.setVisibility(View.INVISIBLE);      iv_arrow.setVisibility(View.VISIBLE);      tv_state.setText("下拉刷新");      tv_time.setText("最后刷新:" + getCurrentTime());    }  }  /**   * 取得当前系统的时间,并格式化   */  @SuppressLint("SimpleDateFormat")  private String getCurrentTime() {    SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss");    return format.format(new Date());  }  private OnRefreshListener listener;  public void setOnRefreshListener(OnRefreshListener listener) {    this.listener = listener;  }  public interface OnRefreshListener {    void onPullRefersh();    void onLoadingMore();  }  /**   * SCROLL_STATE_IDLE:闲置状态,就是手指松开 SCROLL_STATE_TOUCH_SCROLL:手指触摸滑动,就是按着来滑动   * SCROLL_STATE_FLING:快速滑动后松开   */  @Override  public void onScroll(AbsListView view, int firstVisibleItem,      int visibleItemCount, int totalItemCount) {    // TODO Auto-generated method stub  }  @Override  public void onScrollStateChanged(AbsListView view, int scrollState) {    if (scrollState == OnScrollListener.SCROLL_STATE_IDLE        && getLastVisiblePosition() == (getCount() - 1)        && !isLoadingMore) {      isLoadingMore = true;      footerView.setPadding(0, 0, 0, 0);// 显示footerView      setSelection(getCount());// 让ListView的最后一条显示出来      if (listener != null) {        listener.onLoadingMore();      }    }  }}

MainActivity的主代码

package com.demo.pullrefresh;import java.util.ArrayList;import java.util.List;import com.demo.pullrefresh.view.RefreshListView;import com.demo.pullrefresh.view.RefreshListView.OnRefreshListener;import android.annotation.SuppressLint;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.os.SystemClock;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity implements OnItemClickListener {  private RefreshListView refreshListView;  private MyAdapter adapter;  private List<String> list ;  @Override  protected void onCreate(Bundle savedInstanceState) {    // TODO Auto-generated method stub    super.onCreate(savedInstanceState);    initView();    initData();  }  private void initView() {    // TODO Auto-generated method stub    // requestWindowFeature(Window.FEATURE_NO_TITLE);    setContentView(R.layout.mainactivity);    refreshListView = (RefreshListView) findViewById(R.id.rf_mainlistview);  }  private void initData() {    list = new ArrayList<String>();    for (int i = 0; i < 30; i++) {      list.add("ListView原来的数据——  " + i);    }    adapter = new MyAdapter();    refreshListView.setAdapter(adapter);    refreshListView.setOnRefreshListener(new OnRefreshListener() {      @Override      public void onPullRefersh() {        // TODO Auto-generated method stub        // 需要联网请求服务器的数据,然后更新UI        requestDataFromServer(false);      }      @Override      public void onLoadingMore() {        // TODO Auto-generated method stub        requestDataFromServer(true);      }    });    refreshListView.setOnItemClickListener(this);  }  @SuppressLint("HandlerLeak")  private Handler handler = new Handler() {    @Override    public void handleMessage(Message msg) {      // 跟新UI      adapter.notifyDataSetChanged();      refreshListView.completeRefresh();    }  };  /**   * 模拟向服务器请求数据   *   * @param isLoadingMore   */  private void requestDataFromServer(final boolean isLoadingMore) {    new Thread() {      public void run() {        SystemClock.sleep(3000);// 模拟请求服务器的一个时间长度        Log.d("jiejie", isLoadingMore + "");        if (isLoadingMore) {          list.add("加载了更多的数据 ————1");          list.add("加载了更多的数据 ————2");          list.add("加载了更多的数据 ————3");        } else {        }        handler.sendEmptyMessage(0);      };    }.start();  }  @Override  public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {    // TODO Auto-generated method stub    Toast.makeText(MainActivity.this, "第" + arg2 + "个条目== " + list.get(arg2-1),        Toast.LENGTH_SHORT).show();  }  private class MyAdapter extends BaseAdapter {    @Override    public int getCount() {      // TODO Auto-generated method stub      return list.size();    }    @Override    public Object getItem(int arg0) {      // TODO Auto-generated method stub      return null;    }    @Override    public long getItemId(int arg0) {      // TODO Auto-generated method stub      return 0;    }    @Override    public View getView(int arg0, View arg1, ViewGroup arg2) {      // TODO Auto-generated method stub      TextView textView = new TextView(MainActivity.this);      textView.setPadding(20, 20, 20, 20);      textView.setTextSize(18);      textView.setText(list.get(arg0));      return textView;    }  }}