【Android】第三方ONE开发之上拉加载更多的ListView

【Android】第三方ONE开发之上拉加载更多的ListView

前言

由于项目中需要用到刷新的功能以及上拉加载更多的功能,下拉刷新的功能可以通过SwipeRefreshLayout来完成,在只需要实现上拉加载更多即可。因此在这里重载ListView自定义了一个LoadMoreListView,用于支持ListView的上拉加载更多。

LoadMoreListView

效果展示

我们的LoadMoreListView所要实现的效果如下图,也就是上拉时开始加载更多内容,并显示一个正在加载更多的footer,当加载完成后,则去除该footer。

实现

要实现这样一个上拉加载更多的ListView,首先我们需要给它一个footer,用于在底部告知用户正在加载更多的内容。这里我们简单地用一个ProgressBar+TextView来实现。

<?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="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/foot_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:paddingTop="10dp"
        android:paddingBottom="10dp">

        <ProgressBar
            android:layout_width="20dp"
            android:layout_height="20dp" />

        <TextView
            android:id="@+id/foot_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="正在加载更多..." />
    </LinearLayout>
</LinearLayout>

之后,我们就可以编写LoadMoreListView的代码了。

我们的控件是继承自ListView,这个毋庸置疑。我们先通过LayoutInflater拿到了footer_view,并调用ListView的addFooterView方法来为其设置footer同时设置其不可见,然后我们实现了AbsListView的OnScrollListener接口,AbsListView是ListView的父类,通过重写接口中的两个方法我们可以来判断当前是否滚动到了ListView的底部,若滚动到了,并且已经停止滚动,则开始加载数据并显示footer。加载完毕后,我们需要手动调用setLoadCompleted方法来告知LoadMoreListView已加载完毕,并且隐藏footer。

public class LoadMoreListView extends ListView implements AbsListView.OnScrollListener {

    private View mFooter;
    private int mTotalItemCount;
    private int mLastVisbleItem;
    private boolean isLoading;
    private OnLoadMoreListener mListener;

    public LoadMoreListView(Context context) {
        super(context);
        initView(context);
    }

    public LoadMoreListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public LoadMoreListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private void initView(Context context) {
        LayoutInflater inflater = LayoutInflater.from(context);
        //用LayoutInflater初始化底部布局
        mFooter = inflater.from(context).inflate(R.layout.footer_layout, null);
        mFooter.setVisibility(GONE);    //设置底部布局默认不可见
        addFooterView(mFooter);
        setOnScrollListener(this);  //设置滚动监听
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (mTotalItemCount == mLastVisbleItem && scrollState == SCROLL_STATE_IDLE) {
            //如果滚动到底端最后一个并且滚动停止了
            if (!isLoading) {
                //如果此时并非正在加载
                isLoading = true;
                mFooter.setVisibility(VISIBLE);   //显示底部布局
                mListener.onLoadMore();
            }
        }
    }

    public void setLoadCompleted() {
        //加载完成,取消显示footer
        isLoading = false;
        mFooter.setVisibility(GONE);
    }

    public void setFooterText(String text) {
        TextView footText = mFooter.findViewById(R.id.foot_text);
        footText.setText(text);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
            int totalItemCount) {
        this.mLastVisbleItem = firstVisibleItem + visibleItemCount;
        this.mTotalItemCount = totalItemCount;
    }

    public void setLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
        mListener = onLoadMoreListener;
    }

    //加载更多数据的回调接口
    public interface OnLoadMoreListener {

        void onLoadMore();
    }
}

这样,我们的LoadMoreListView就成功实现了,使用的时候只需要像正常ListView使用并为它添加加载更多数据的回调接口即可。不过要记住的是,数据加载完毕时需要手动通知它已经加载完毕。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: