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事件,之前的 下拉刷新 逻辑,屏幕要随着手指变化而有所变化,down、move、up所以需要随时监听不同状态。
但是现在是 上拉加载 逻辑,只需满足 滑动条目到底 时这一个条件 ,即可开始刷新,至于之前的手指动作都无所谓,所以在这里开启监听 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;
}
}
写到这里就差不多将 下拉刷新和上拉加载 的重点介绍完了,其实两者都是大同小异,但是互相都有些耦合的地方,一步步敲代码过来才能体会其中含义,一点点学习吧,希望对你们有帮助 :)
代码待我整理整理再发出来