封装ListView,实现自动加载更多

如今网上关于封装ListView,实现加载更多和下拉刷新的文章已经铺天盖地的了,基本都是通过addHeaderView()和addFooterView(),设置下拉头和上拉底部,然后通过OnScrollListener监听器的onScroll方法中判断是否滑动到底部。

判断滑动到底部还是头部:

 if (firstVisibleItem == 0) {
            Log.i("ListView", "滚动到顶部");
        } else if ((firstVisibleItem + visibleItemCount) == totalItemCount) {
            Log.i("ListView", "滚动到底部");
 }
复制代码

理论都是万变不离其宗。

这是我封装之后得到的效果图。

以下是封装控件的实现。

public class LoadMoreListView extends ListView {

    private RelativeLayout mFooterView;
    private LinearLayout layout;
    private ProgressBar progressBar;
    private TextView textView;
    private boolean mIsLoadingMore = false;
    private boolean mHasMore = true;

    private LoadMoreListener loadMoreListener;
    private OnCustomScrollListener onCustomScrollListener;


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

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

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

    private void initlize(Context context) {
        initView(context);
        initListener(context);
        //添加footerview
        addFooterView(mFooterView);
        hideLoadingView();
    }

    private void initView(Context context) {

        mFooterView = new RelativeLayout(context);
        RelativeLayout.LayoutParams rParams;
        LinearLayout.LayoutParams lParams;

        rParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        rParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        layout = new LinearLayout(context);
        layout.setOrientation(LinearLayout.HORIZONTAL);
        layout.setGravity(Gravity.CENTER_VERTICAL);
        mFooterView.addView(layout, rParams);

        lParams = new LinearLayout.LayoutParams(60, 60);
        lParams.weight = Gravity.CENTER_VERTICAL;
        progressBar = new ProgressBar(context);
        layout.addView(progressBar, lParams);

        lParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        lParams.leftMargin = 10;
        textView = new TextView(context);
        textView.setText("正在加载...");
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
        layout.addView(textView, lParams);
    }


    private void initListener(Context context) {
        setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (onCustomScrollListener != null) {
                    onCustomScrollListener.onScrollStateChanged(view, scrollState);
                }


            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (onCustomScrollListener != null) {
                    onCustomScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
                }
                if (mFooterView.getParent() != null && !mIsLoadingMore && mHasMore) {
                    layout.setVisibility(View.VISIBLE);
                    mFooterView.setVisibility(View.VISIBLE);
                    if (loadMoreListener != null) {
                        loadMoreListener.loadMore();
                    }
                    showLoadingView();
                }

            }
        });
    }


    /**
     * 设置OnCustomScrollListener回调
     *
     * @param listener
     */
    public void setOnCustomScrollListener(OnCustomScrollListener listener) {
        this.onCustomScrollListener = listener;
    }

    /**
     * OnScrollListener的回调接口
     */
    public interface OnCustomScrollListener {
        void onScrollStateChanged(AbsListView view, int scrollState);

        void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount);
    }

    /**
     * 设置加载更多回调接口
     *
     * @param listener
     */
    public void setLoadMoreListener(LoadMoreListener listener) {
        this.loadMoreListener = listener;
    }

    /**
     * 加载更多回调接口
     */
    public interface LoadMoreListener {
        void loadMore();
    }

    /**
     * 是否还有更多
     *
     * @param hasMore
     */
    public void setHasMore(boolean hasMore) {
        mHasMore = hasMore;
    }

    /**
     * 隐藏加载loading
     */
    private void hideLoadingView() {
        progressBar.setVisibility(View.GONE);
        layout.setVisibility(View.GONE);
        mFooterView.setVisibility(GONE);
    }

    /**
     * 显示loading
     */
    private void showLoadingView() {
        progressBar.setVisibility(View.VISIBLE);
        layout.setVisibility(View.VISIBLE);
        mFooterView.setVisibility(View.VISIBLE);
    }

    /**
     * 加载更多结束
     * 加载完成后调用
     */
    public void loadMoreFinish() {
        mIsLoadingMore = false;
        hideLoadingView();
    }

    /**
     * 正在加载更多
     * 加载中调用
     */
    public void isLoadingMore() {
        mIsLoadingMore = true;
        showLoadingView();
    }


}
复制代码

LoadMoreListView是经过封装的listview。initview函数:初始化footerview,然后通过addFooterView()将footerview加到listview中,而footerview的作用就是告诉用户,正在加载数据。通过设置mIsLoadingMore和mHasMore,是否触发回调函数,如果触发回调函数就是需要加载数据。里面设置了各种方法,大家可以看看注释,都是比较简单的封装。

下面我们看看如何使用

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.lwj.loadmore.LoadMoreActivity">
    <com.lwj.loadmore.LoadMoreListView
        android:id="@+id/load_more_list"
        android:layout_width="match_parent"
        android:background="#ffffff"
        android:dividerHeight="0dp"
        android:divider="@null"
        android:layout_height="match_parent"/>

</android.support.constraint.ConstraintLayout>

复制代码

这是布局文件。

public class LoadMoreActivity extends BaseActivity {

    private LoadMoreListView loadMoreListView;
    private List<String> datas = new ArrayList<>();
    private ListAdapter adapter;
    private int page = 1;
    private int pagesize = 30;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_load_more);
        loadMoreListView = (LoadMoreListView)this.findViewById(R.id.load_more_list);
        adapter = new ListAdapter(LoadMoreActivity.this,datas);
        loadMoreListView.setAdapter(adapter);
        initListener();
    }

    /**
     * 初始化事件监听
     */
    private void initListener() {
        /**
         * 加载更多
         */
        loadMoreListView.setLoadMoreListener(new LoadMoreListView.LoadMoreListener() {
            @Override
            public void loadMore() {
                loadMoreListView.isLoadingMore();
                getDataFromService();
            }
        });

    }

    private void getDataFromService(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                getDatas();
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        setData();
                    }
                });

            }
        }).start();
    }

    /**
     * 设置数据
     */
    private void setData() {
        loadMoreListView.loadMoreFinish();
        adapter.notifyDataSetChanged();
        if (page == 3){
            loadMoreListView.setHasMore(false);
        }
        page++;
    }

    /**
     * 获取数据
     */
    public void getDatas() {
        int i = 0;
        if (page == 1){
            i = page -1;
        }else{
           i = (page-1)*pagesize;
        }
        for (; i < (page*pagesize); i++) {
            String str = "加载更多的tiem——"+i;
            datas.add(str);
        }
    }
}
复制代码

使用很简单,初始化view,然后设置回调方法,在回调方法中去获取数据,同时调用loadMoreListView.isLoadingMore()方法,显示加载的loading。

加载数据完成之后,需要调用loadMoreListView.loadMoreFinish(),这个方法隐藏掉loading同时设置mIsLoadingMore,如果没有设置setHasMore(false),滑动到底部会触发加载更多的回调,继续加载数据。

public class ListAdapter extends BaseAdapter {
    private List<String> datas;
    private Context mContext;

    public ListAdapter(Context mContext,List<String> datas) {
        this.datas = datas;
        this.mContext = mContext;
    }

    @Override
    public int getCount() {
        return datas == null ? 0 : datas.size();
    }

    @Override
    public Object getItem(int i) {
        return datas == null ? null : datas.get(i);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {
        if (convertView == null && !(convertView instanceof ItemLayout)){
            convertView = new ItemLayout(mContext);
        }
        ((ItemLayout)convertView).setData(datas.get(position));
        return convertView;
    }

    public static class ItemLayout extends LinearLayout{
        public String tagStr;
        private Button mButton;

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

        private void initView(Context context) {
            int MP = LinearLayout.LayoutParams.MATCH_PARENT;
            int WC = LinearLayout.LayoutParams.WRAP_CONTENT;
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(MP, WC);
            LinearLayout layout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.list_item_layout,null);
            addView(layout,params);
            mButton = (Button)layout.findViewById(R.id.text);
        }
        public void setData(String str){
            if (str == null || str == tagStr){
                return;
            }else{
                tagStr = str;
                mButton.setText(str);
            }
        }

    }
}

复制代码

这是listview的adapter,主要显示数据,比较简单。

整个封装和使用已经完成了,希望对大家有所帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值