自定义ListView实现下拉刷新,上拉加载更多

  • 自定义ListView类
public class RefreshListView extends ListView implements AbsListView.OnScrollListener {

    private View headView;
    private View footView;
    private TextView tv_head_showMsg,tv_foot_showMsg;
    private ProgressBar pb_head,pb_foot;
    private int headViewHeight;//头部View的高度
    private int footViewHeight;//
    private int downY;
    private final int pull_refresh = 0;//下拉刷新
    private final int isRefreshing = 1;//正在刷新
    private final int releaseToRefresh = 2;//松开手机刷新
    private int currentStatus = pull_refresh;//当前刷新的状态
    private onRefreshListener mRefreshListener;
    private boolean isLoadMore = false;//是否加载更多

    public RefreshListView(Context context) {
        this(context, null);
    }

    public RefreshListView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        initHeadView();
        initFooterView();
        this.setOnScrollListener(this);
    }
    /**
     * 初始化头部布局
     */
    private void initHeadView() {
        headView = View.inflate(getContext(), R.layout.refreshheadview, null);
        tv_head_showMsg = (TextView) headView.findViewById(R.id.tv_showMsg);
        pb_head = (ProgressBar) headView.findViewById(R.id.pb_head);
        headView.measure(0, 0);//主动通知系统去测量该view
        headViewHeight = headView.getMeasuredHeight();
        setTopPadding(-headViewHeight);
        this.addHeaderView(headView);
    }
    /**
     * 初始化底部布局
     */
    private void initFooterView() {
        footView = View.inflate(getContext(), R.layout.refreshfootview, null);
        tv_foot_showMsg = (TextView) footView.findViewById(R.id.tv_foot_showMsg);
        pb_foot = (ProgressBar) footView.findViewById(R.id.pb_foot);
        footView.measure(0, 0);
        footViewHeight = footView.getMeasuredHeight();
        setBottomPadding(-footViewHeight);
        this.addFooterView(footView);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (currentStatus == isRefreshing) {
                    break;
                }
                int moveY = (int) (ev.getY() - downY);
                int headPadding = moveY - headViewHeight;
                if (headPadding > -headViewHeight && getFirstVisiblePosition() == 0) {
                    setTopPadding(headPadding);
//                    Toast.makeText(getContext(),"超过头部高度拉",Toast.LENGTH_LONG).show();
                    if (headPadding > 0 && currentStatus == pull_refresh) {//从下拉刷新到松开刷新
                        currentStatus = releaseToRefresh;
                    } else if (headPadding < 0 && currentStatus == releaseToRefresh) {//回到下拉刷新
                        currentStatus = pull_refresh;
                    }
                    updateHeadView();
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (currentStatus == pull_refresh) {
                    setTopPadding(-headViewHeight);
                } else if (currentStatus == releaseToRefresh) {
                    setTopPadding(0);
                    currentStatus = isRefreshing;
                    updateHeadView();
                    if (mRefreshListener != null) {
                        mRefreshListener.onPullRefresh();
                    }
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    //设置headView的顶部边距
    private void setTopPadding(int topPadding) {
        if (headView != null) {
            headView.setPadding(0, topPadding, 0, 0);
        }
    }

    //设置footView的底部边距
    private void setBottomPadding(int bottomPadding) {
        if (footView != null) {
            footView.setPadding(0, bottomPadding, 0, 0);
        }
    }

    /**
     * 更新headView状态,
     */
    private void updateHeadView() {
        switch (currentStatus) {
            case pull_refresh:
                tv_head_showMsg.setText("下拉刷新");
                pb_head.setVisibility(View.GONE);
                break;
            case releaseToRefresh:
                tv_head_showMsg.setText("松开刷新");
                break;
            case isRefreshing:
                tv_head_showMsg.setText("正在刷新...");
                pb_head.setVisibility(View.VISIBLE);
                break;
        }
    }

    /**
     * SCROLL_STATE_IDLE:闲置状态,就是手指松开
     * SCROLL_STATE_TOUCH_SCROLL:手指触摸滑动,就是按着来滑动
     * SCROLL_STATE_FLING:快速滑动后松开
     */

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == SCROLL_STATE_IDLE && getLastVisiblePosition() + 1 == getCount() && !isLoadMore) {
            isLoadMore = true;
            setBottomPadding(0);
//            footView.setVisibility(View.VISIBLE);
            setSelection(getCount());
            tv_foot_showMsg.setText("正在刷新...");
            pb_foot.setVisibility(View.VISIBLE);
            if (mRefreshListener != null) {
                mRefreshListener.onLoadMore();
            }
        }
//        else {
//            setBottomPadding(-footViewHeight);
//        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }

    /**
     * 刷新完成
     */
    public void refreshComplete() {
        if (isLoadMore) {
            setBottomPadding(-footViewHeight);
//            footView.setVisibility(View.GONE);
            pb_foot.setVisibility(View.GONE);
            isLoadMore = false;
        } else {
            setTopPadding(-headViewHeight);
            tv_head_showMsg.setText("下拉刷新");
            pb_head.setVisibility(View.GONE);
            currentStatus = pull_refresh;
        }
    }

    /**
     * 刷新事件监听
     * @param refreshListener
     */
    public void setOnRefreshListener(onRefreshListener refreshListener) {
        this.mRefreshListener = refreshListener;
    }
    /**
     * 接口回调模式
     */
    public interface onRefreshListener {
        void onPullRefresh();

        void onLoadMore();
    }

    /**
     * 适配器模式
     */
    public static class RefreshAdapter implements onRefreshListener {

        @Override
        public void onPullRefresh() {

        }

        @Override
        public void onLoadMore() {

        }
    }
}
  • MainActivity
public class MainActivity extends Activity {

    private RefreshListView lv;
    private List<String> list;
    private myAdapter adapter;
    private int addHeadItem = 0;
    private int addFootItem = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("simple");
        }
        lv = (RefreshListView) findViewById(R.id.lv);
        adapter = new myAdapter();
        lv.setAdapter(adapter);
        //接口回调方式
        lv.setOnRefreshListener(new RefreshListView.onRefreshListener() {
            @Override
            public void onPullRefresh() {
                list.add(0, "pull_refresh" + addHeadItem);
                addHeadItem++;
                lv.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        adapter.notifyDataSetChanged();
                        lv.refreshComplete();
                    }
                }, 3000);

            }

            @Override
            public void onLoadMore() {

                lv.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 5; i++) {
                            list.add("onLoadMore" + addFootItem);
                            addFootItem++;
                        }
                        adapter.notifyDataSetChanged();
                        lv.refreshComplete();
                    }
                }, 3000);
            }
        });
        //适配器模式
//        lv.setOnRefreshListener(new RefreshListView.RefreshAdapter() {
//            @Override
//            public void onPullRefresh() {
//                super.onPullRefresh();
//                for (int i = 0; i < 20; i++) {
//                    list.add(0, "pull_refresh" + i);
//                }
//                adapter.notifyDataSetChanged();
//                lv.postDelayed(new Runnable() {
//                    @Override
//                    public void run() {
//                        lv.refreshComplete();
//                    }
//                }, 3000);
//            }
//        });
    }

    private class myAdapter extends BaseAdapter {


        @Override
        public int getCount() {
            return list.size();
        }


        @Override
        public Object getItem(int position) {
            return null;
        }


        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = View.inflate(MainActivity.this, R.layout.convert_item, null);
                holder.tv = (TextView) convertView.findViewById(R.id.tv);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.tv.setText(list.get(position));
            return convertView;
        }

        class ViewHolder {
            TextView tv;
        }
    }
}
  • headView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#00000000">

        <ProgressBar
            android:id="@+id/pb_head"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:visibility="gone"
            />

        <TextView
            android:id="@+id/tv_showMsg"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:gravity="center_vertical"
            android:text="这是下拉刷新头部"
            android:textSize="18sp" />
    </RelativeLayout>
</RelativeLayout>
  • footView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#66FFFFFF">

        <ProgressBar
            android:id="@+id/pb_foot"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:visibility="gone" />

        <TextView
            android:id="@+id/tv_foot_showMsg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="上拉加载更多"
            android:textSize="15sp" />
    </RelativeLayout>
</RelativeLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值