Android 中 ListView 的 下拉刷新 和 上拉加载 的 重点及学习(二)

http://blog.csdn.net/ITermeng/article/details/52297286
转载请注明出处,阿里噶多~


一鼓作气,昨天写了下拉刷新,今天把 上拉加载也写完,不然又要拖好久了……大家都知道,编程时容易,写下来的话要斟酌许久,有错误也请大家指示一下,学习学习 :)

(如果是第一次看我的这篇博客的朋友,建议你们先去看一下(一),再来看二)


这里写图片描述

如上gif动图所示,接下来我们要完成 【 上拉加载 】 的实现。(其实看了下拉刷新的朋友,熟悉了步骤之后,再看这个 上拉加载,发现都是差不多啦~)



一. 完成 xml 文件的编写 :


1. 完成listView的 脚布局

这里写图片描述

如上图所示,一个线性布局,这个ProgressBar 直接用我们在 下拉刷新 中自定义的就好了。

<?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="wrap_content"
    android:gravity="center"
    android:orientation="horizontal" >

    <ProgressBar
        android:layout_margin="5dp"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:indeterminateDrawable="@drawable/shape_progress" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加载更多..."
        android:textColor="#F00"
        android:layout_marginLeft="15dp"
        android:textSize="18sp" />

</LinearLayout>


二. 完成逻辑编写实现上拉加载 :

1. (老规矩)初始化 脚布局

初始化后,测得脚布局高度,将它隐藏起来。

/**
 * 初始化脚布局
 */
private void initFooterView() {
    mFooterView = View.inflate(getContext(),R.layout.refresh_listview_footer, null);
    this.addFooterView(mFooterView);

    mFooterView.measure(0, 0);// 测量View
    mFooterHeight = mFooterView.getMeasuredHeight();
    mFooterView.setPadding(0, -mFooterHeight, 0, 0);// 隐藏头布局

    setOnScrollListener(this);
}


2. 设置监听,是否滑到底(重点!!!)

顺着思路考虑,将脚布局隐藏起来后,现在要通过手指的滑动来判断 是否滑到了条目第,符合条件后才会触发 上拉刷新 的逻辑。

注意!这时用的不再是 onTouchEvent事件,之前的 下拉刷新 逻辑,屏幕要随着手指变化而有所变化downmoveup所以需要随时监听不同状态
但是现在是 上拉加载 逻辑,只需满足 滑动条目到底 时这一个条件 ,即可开始刷新,至于之前的手指动作都无所谓,所以在这里开启监听 OnScrollListener 即可。

//    public static int SCROLL_STATE_IDLE = 0; // 空闲
//    public static int SCROLL_STATE_TOUCH_SCROLL = 1; // 触摸滑动
//    public static int SCROLL_STATE_FLING = 2; // 滑翔

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // 状态更新的时候
        System.out.println("scrollState: " + scrollState);
        if(isLoadingMore){
            return; // 已经在加载更多.返回
        }

        // 最新状态是空闲状态, 并且当前界面显示了所有数据的最后一条. 加载更多
        if(scrollState == SCROLL_STATE_IDLE && getLastVisiblePosition() >= (getCount() - 1)){
            isLoadingMore = true;
            System.out.println("scrollState: 开始加载更多");
            mFooterView.setPadding(0, 0, 0, 0);

            setSelection(getCount()); // 跳转到最后一条, 使其显示出加载更多.

            if(mListener != null){
                mListener.onLoadMore();
            }
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        // 滑动过程
    }


大家在这里一定要明确 触摸事件滑动事件 的区别:

触摸事件: 下拉刷新 监听了手指在屏幕上各个不同的事件(最基本的dowm、move、up)
滑动事件: 上拉加载 这里只监听屏幕滑动 和 状态改变 两个事件。

这里写图片描述



首先要了解 滑动 的三个状态:(这里有点特殊,在滑动监听中,三种状态已经定义好,不需要我们再定义)

(1)SCROLL_STATE_IDLE 空闲:字面意思,即屏幕未滑动。
(2)SCROLL_STATE_TOUCH_SCROLL 触摸滑动:手指在屏幕上滑动,此过程中手指一直接触屏幕
(3)SCROLL_STATE_FLING 滑翔:与状态2 易混淆,比如手指快速一滑,屏幕中条目迅速变动,但是此时手指已脱离屏幕,即未接触屏幕


其次从 onScrollStateChanged状态改变onScroll滑动过程 这两个事件来分析逻辑:

滑动过程中的变化不需要有所监听,我们开启上拉加载的唯一条件就是:条目到底! 所以只关注 onScrollStateChanged状态改变 事件:

1. 当前状态为“正在刷新”,即不处理(也不看第二点了,return出去)。

    2.   判断条件也很简单,不如  下拉刷新 复杂 ,只要获取当前条目,判断 当前状态为 空闲 后,当前条目为最后一个  且  尚未在加载,----->即可开启加载条目逻辑。



3. 设置回调接口给“加载更多”逻辑 (重点!!!)

回调真的是太常用了,手指滑动将屏幕拉到底后,触发事件,回调 调用onLoadMore()方法加载更多数据。(这里将上拉加载和下拉刷新一起写了,就是在接口里多加个方法)

(1)上拉加载的回调接口

public interface OnRefreshListener {
        void onRefresh(); // 下拉刷新

        void onLoadMore();// 加载更多
    }


(2)暴露接口,设置监听

    public void setOnRefreshListener(OnRefreshListener listener) {
        mListener = listener;
    }


(3)定义成员变量,接收监听对象

private OnRefreshListener mListener;


(4) 在合适的地方进行回调
(之前第二点中onScrollStateChanged事件中进行回调)

            if(mListener != null){              //通知主界面加载下一页数据
                mListener.onLoadMore();
            }


5. 前端界面设置回调(并非RefreshListView类,是使用了该listView类中写!!!)

    lvList.setOnRefreshListener(new OnRefreshListener() {

            @Override
            public void onRefresh() {
                // 刷新数据

            }
                        @Override
            public void onLoadMore() {
                //加载数据
            }
        });


4. 加载结束,隐藏控件

最后一步,收尾动作,数据加载完后,隐藏控件,在做完 下拉刷新 后,其实已经写了一个onRefreshComplete方法,收起头布局,这个时候其实没有必要再写一个,在方法头加一个参数用来判断 是 上拉加载 还是下拉刷新 从而隐藏不同控件和修改状态。

/**
     * 刷新结束或加载结束,收起控件
     */
    public void onRefreshComplete(boolean success) {
        if (!isLoadingMore) {
            mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);

            mCurrentState = STATE_PULL_TO_REFRESH;
            tvTitle.setText("下拉刷新");
            pbProgress.setVisibility(View.INVISIBLE);
            ivArrow.setVisibility(View.VISIBLE);

            if (success) {// 只有刷新成功之后才更新时间
                setCurrentTime();
            }
        } else {
            //加载更多
            mFooterView.setPadding(0, -mFooterViewHeight, 0, 0);//隐藏布局
            isLoadingMore = false;

        }
    }


写到这里就差不多将 下拉刷新和上拉加载 的重点介绍完了,其实两者都是大同小异,但是互相都有些耦合的地方,一步步敲代码过来才能体会其中含义,一点点学习吧,希望对你们有帮助 :)

代码待我整理整理再发出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值