Android开发笔记之ListView下拉刷新实现机制

来源:互联网 发布:php开发入门教程 编辑:程序博客网 时间:2024/06/04 18:10
package com.example.listviewdemo;import com.example.listviewdemo.R;import android.content.Context;import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.TextView;public class RefreshListView extends ListView implements AbsListView.OnScrollListener{    private static final int REFRESH_DONE=0;//下拉刷新完成    private static final int PULL_TO_REFRESH=1;//下拉中(下拉高度未超出headview高度)    private static final int RELEASH_TO_REFRESH=2;//准备刷新(下拉高度超出headview高度)    private static final int REFRESHING=3;//刷新中    private static final float REFRESH_RATIO=3.0f;//下拉系数,越大下拉灵敏度越低    private LinearLayout headerView;//headview布局    private int headerViewHeight;//headview高度    private int refreshstate;//下拉刷新状态    private boolean isScrollFirst;//是否滑动到顶部    private TextView tv_refresh;    private float startY,offsetY;    //监听接口    private OnRefreshListener mOnRefreshListener;    public RefreshListView(Context context) {        super(context);        init(context);    }    public RefreshListView(Context context,AttributeSet attrs) {        super(context,attrs);        init(context);    }    public RefreshListView(Context context, AttributeSet attrs,            int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    /**     * 初始化view     * @param context     */    private void init(Context context){        setOverScrollMode(View.OVER_SCROLL_NEVER);        setOnScrollListener(this);        headerView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.listview_head_view, null,false);        tv_refresh = (TextView) headerView.findViewById(R.id.tv_refresh);        measureView(headerView);        addHeaderView(headerView);        headerViewHeight = headerView.getMeasuredHeight();        headerView.setPadding(0, -headerViewHeight, 0, 0);        refreshstate = REFRESH_DONE;    }    public void onScrollStateChanged(AbsListView absListView,int i){    }    public void onScroll(AbsListView absListView,int firstVisibleItem,int visibleItemCount,int totalItemCount){        if(firstVisibleItem==0){            isScrollFirst=true;        }else{            isScrollFirst=false;        }    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {        case MotionEvent.ACTION_DOWN:            startY=ev.getY();            break;        case MotionEvent.ACTION_MOVE:            offsetY=ev.getY()-startY;            if(offsetY > 0 && isScrollFirst && refreshstate!=REFRESHING){                float headerViewShowHeight = offsetY/REFRESH_RATIO;                switch (refreshstate) {                case REFRESH_DONE:                    refreshstate=PULL_TO_REFRESH;                    break;                case PULL_TO_REFRESH:                    setSelection(0);                    if(headerViewShowHeight-headerViewShowHeight>=0){                        refreshstate = RELEASH_TO_REFRESH;                        changeHeaderByState(refreshstate);                    }                    break;                case RELEASH_TO_REFRESH:                    setSelection(0);                    if (headerViewShowHeight - headerViewHeight < 0) {                        refreshstate = PULL_TO_REFRESH;                        changeHeaderByState(refreshstate);                    }                    break;                }                if(refreshstate == PULL_TO_REFRESH || refreshstate == RELEASH_TO_REFRESH){                    headerView.setPadding(0, (int) (headerViewShowHeight-headerViewHeight), 0, 0);                }            }            break;        case MotionEvent.ACTION_UP:            if (refreshstate == PULL_TO_REFRESH) {                refreshstate = REFRESH_DONE;                changeHeaderByState(refreshstate);            }            if (refreshstate == RELEASH_TO_REFRESH) {                refreshstate = REFRESHING;                changeHeaderByState(refreshstate);                mOnRefreshListener.onRefresh();            }            break;                }        return super.onTouchEvent(ev);    }    /**     * 改变headview状态     * @param state     */    private void changeHeaderByState(int state){        switch (state) {        case REFRESH_DONE:            headerView.setPadding(0, -headerViewHeight, 0, 0);            tv_refresh.setText("下拉刷新");            break;        case RELEASH_TO_REFRESH:            tv_refresh.setText("下拉刷新");            break;        case PULL_TO_REFRESH:            tv_refresh.setText("下拉刷新");            break;        case REFRESHING:            headerView.setPadding(0, 0, 0, 0);            tv_refresh.setText("正在刷新");            break;        default:            break;        }    }    /**     * 下拉刷新监听     */    public interface OnRefreshListener{        void onRefresh();    }    /**     * 设置下拉刷新     * @param onRefreshListener     */    public void setOnRefreshListener(OnRefreshListener onRefreshListener){        mOnRefreshListener=onRefreshListener;    }    /**     *下拉刷新完成     */    public void setOnRefreshComplete(){        refreshstate=REFRESH_DONE;        changeHeaderByState(refreshstate);    }    /**     * 计算空间的高度     * @param child     */    private void measureView(View child){        ViewGroup.LayoutParams p = child.getLayoutParams();        if (p==null){            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,                     ViewGroup.LayoutParams.WRAP_CONTENT);        }        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0+0, p.width);        int lpHeight = p.height;        int childHeightspc;        if (lpHeight>0){            childHeightspc = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);        }else{            childHeightspc = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);        }        child.measure( childWidthSpec, childHeightspc);    }}

package com.example.listviewdemo;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ArrayAdapter;import android.widget.Toast;public class MainActivity extends Activity implements RefreshListView.OnRefreshListener {    private RefreshListView mListView;    private List<String> mDatas;    private ArrayAdapter<String> mAdapter;    private final static int REFRESH_COMOLETE=0;    private Handler mHandler = new Handler(){        public void handleMessage(Message msg){            switch (msg.what) {            case REFRESH_COMOLETE:                mListView.setOnRefreshComplete();                mAdapter.notifyDataSetChanged();                mListView.setSelection(0);                break;            }        };    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView(){        mListView = (RefreshListView) findViewById(R.id.listview);        String[] data = new String[]{"下拉刷新","下拉刷新","下拉刷新",                "下拉刷新","下拉刷新","下拉刷新","下拉刷新","下拉刷新"                ,"下拉刷新","下拉刷新","下拉刷新","下拉刷新"};        mDatas = new ArrayList<>(Arrays.asList(data));        mAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, mDatas);        mListView.setAdapter(mAdapter);        mListView.setOnRefreshListener(this);        mListView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                // TODO Auto-generated method stub                Toast.makeText(MainActivity.this, "position=" + position, Toast.LENGTH_SHORT).show();            }        });    }    public void onRefresh(){        new Thread(){            public void run(){                try {                    Thread.sleep(3000);                    mDatas.add(0,"new下拉刷新");                    mHandler.sendEmptyMessage(REFRESH_COMOLETE);                } catch (Exception e) {                    // TODO: handle exception                }            }        }.start();    }}
0 0