Android项目:使用pulltorefresh开源项目扩展为下拉刷新上拉加载更多的处理方法,监听listview滚动方向-阿里云开发者社区

开发者社区> 余二五> 正文

Android项目:使用pulltorefresh开源项目扩展为下拉刷新上拉加载更多的处理方法,监听listview滚动方向

简介:
+关注继续查看

很多android应用的下拉刷新都是使用的pulltorefresh这个开源项目,但是它的扩展性在下拉刷新同时又上拉加载更多时会有一定的局限性。查了很多地方,发现这个开源项目并不能很好的同时支持下拉刷新和上拉加载更多。这个组件有个mode的属性,可以设置为both,即上下同时都可拉动。但是只设置这个属性的话,上拉与下拉产生的效果是完全一致的。所以要使用这个开源项目做到下拉刷新并同时可上拉加载更多,就需要在代码中进行一些处理。



==========================pulltorefresh属性相关=====================================

开源项目:Android-PullToRefresh

项目地址:https://github.com/chrisbanes/Android-PullToRefresh/wiki/Quick-Start-Guide


1.属性:https://github.com/chrisbanes/Android-PullToRefresh/blob/master/library/res/values/attrs.xml

命名空间: xmlns:ptr="http://schemas.android.com/apk/res-auto"

ptr:ptrAnimationStyle 动画效果 提供了两个值 flip和rotate 默认为rotate
ptr:ptrRefreshableViewBackground 设置刷新View的背景颜色
ptr:ptrHeaderBackground 设置头部View的背景颜色
ptr:ptrHeaderTextColor 设置头部View文字的颜色
ptr:ptrHeaderSubTextColor 设置头部view副标题文字的颜色
ptr:ptrMode

pullFromStart:

pullFromEnd:

both;


2.常用方法

setOnRefreshListener(OnRefreshListener listener):设置刷新监听器;

setOnLastItemVisibleListener(OnLastItemVisibleListener listener):设置是否到底部监听器;

setOnPullEventListener(OnPullEventListener listener);设置事件监听器;

onRefreshComplete():设置刷新完成


==========================监听listview滚动方向=====================================


修改为上拉加载更多的关键在于onrefresh方法执行之前判断出listview的滚动方向。以下方法是所尝试的方法中效果最好的一种,并不能说完美解决,但应该是效果最接近的一种了。(当首屏数据行数未充满屏幕,或者滚动时第一行的滚动距离小于行高,可能还是会存在一点误差。不过大部分应用的列表每页数据一般都能充满屏幕,也可在此基础结合其他手势判断对此方法进行改善)。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int mLastFirstVisibleItem = 0;
boolean mIsScrollingUp;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
                                                                                                      
    if (view.getId() == mListView.getId())
    {
        final int currentFirstVisibleItem = mListView.getFirstVisiblePosition();
                                                                                                          
        if (currentFirstVisibleItem > mLastFirstVisibleItem)
        {
            mIsUp = true;
        }
        else if (currentFirstVisibleItem < mLastFirstVisibleItem)
        {
            mIsUp = false;
        }
        mLastFirstVisibleItem = currentFirstVisibleItem;
    }
                                                                                                      
}


参考资料:http://stackoverflow.com/questions/12114963/detecting-the-scrolling-direction-in-the-adapter-up-down/12115157#12115157




==========================实现下拉刷新和上拉加载更多====================================

解析json完毕后,判断是上拉操作还是下拉刷新操作:

1
2
3
4
5
6
7
8
9
10
11
// 解析json
private void parseJson(String result)
{
    List<ListJson> localList = parseJsonArray(Utils.parseListJson(result, "key"));
                                                          
    if(!mIsUp)
    {
        mDataList.clear();
    }
    mDataList.addAll(localList);
}


数据加载完毕后,notifyDataSetChanged和通知PullRefreshListView,同时页码加1:

1
2
3
4
5
6
7
// 加载完毕处理
private void loadComplete()
{
    mPullRefreshListView.onRefreshComplete();
    mAdapter.notifyDataSetChanged();
    mPage += 1;
}


判断上拉和下拉方向,监听刷新listview,修改头部和底部view的文字说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
 * *******************下拉刷新与上拉加载的监听处理************************
 */
// 刷新listview监听
@Override
public void onRefresh(PullToRefreshBase<ListView> refreshView)
{
    // 获取刷新时间,设置刷新时间格式
    String str = DateUtils.formatDateTime(getActivity(), System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON);
                  
    // 判断下拉还是上拉
    if (!mIsUp)
        mPage = 0;
                  
    // 设置刷新文本说明(刷新过程中)
    if (mIsUp)
    {
        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在加载");
        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉加载更多");
        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始加载");
        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后加载时间:" + str);
    }
    else
    {
        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新");
        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉刷新");
        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始刷新");
        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后更新时间:" + str);
    }
                  
    // 启动下载任务,加载数据
    loadTask();
}
int mLastFirstVisibleItem = 0;
boolean mIsScrollingUp;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
                  
    if (view.getId() == mListView.getId())
    {
        final int currentFirstVisibleItem = mListView.getFirstVisiblePosition();
                      
        if (currentFirstVisibleItem > mLastFirstVisibleItem)
        {
            mIsUp = true;
        }
        else if (currentFirstVisibleItem < mLastFirstVisibleItem)
        {
            mIsUp = false;
        }
        mLastFirstVisibleItem = currentFirstVisibleItem;
    }
                  
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
    // 设置刷新文本说明(展开刷新栏前)
    if (mIsUp)
    {
        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在加载");
        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉加载更多");
        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始加载");
    }
    else
    {
        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新");
        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉刷新");
        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始刷新");
    }
                  
}
@Override
public void onLastItemVisible()
{
    mIsUp = true;
}




==========================其他使用笔记====================================

1.PullRefreshListView.setRefreshing()方法无法执行更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
    protected void onRefreshing(final boolean doScroll) {
        /**
         * If we're not showing the Refreshing view, or the list is empty, the
         * the header/footer views won't show so we use the normal method.
         */
        /*ListAdapter adapter = mRefreshableView.getAdapter();
        if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
            super.onRefreshing(doScroll);
            return;
        }*/
        super.onRefreshing(false);
        }
    }

mPullRefreshListView.setRefreshing();如果adapter是里面的size是null 或者大小是0

这个时候 setRefreshing是不会有效果的.需要将PullToRefreshListView上面代码注释掉



2.通过继承OnRefreshListener2<ListView>直接实现上拉与下拉监听,但是下拉窗口的文字无法及时更新,即方法只在下拉操作后才执行。

1
2
3
4
5
6
7
8
9
        mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.refresh_listview);
        mListView = ((ListView) this.mPullRefreshListView.getRefreshableView());
         
        // 监听listview
        mPullRefreshListView.setOnRefreshListener(this);
        // mPullRefreshListView.setOnRefreshListener(this);
        // mPullRefreshListView.setOnLastItemVisibleListener(this);
        // mPullRefreshListView.setOnScrollListener(this);
         mPullRefreshListView.setOnItemClickListener(this);


相应接口方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    @Override
    public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView)
    {
        // 获取刷新时间
        String str = DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON);
         
        // 设置刷新文本说明(刷新过程中)
        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在刷新");
        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉刷新");
        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始刷新");
        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后更新时间:" + str);
         
        onPullDownListView();
    }
     
    public void onPullDownListView()
    {
        // TODO Auto-generated method stub
         
    }
 
    @Override
    public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView)
    {
        // 获取刷新时间
        String str = DateUtils.formatDateTime(this, System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON);
         
        // 设置刷新文本说明(刷新过程中)
        mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在加载");
        mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉加载更多");
        mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("释放开始加载");
        refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最后加载时间:" + str);
         
        onPullUpListView();
    }
 
    public void onPullUpListView()
    {
        // TODO Auto-generated method stub
         
    }




本文转自 glblong 51CTO博客,原文链接:http://blog.51cto.com/glblong/1312349,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
进行微服务治理,先要对微服务进行度量(1)
进行微服务治理,先要对微服务进行度量(1)
10 0
flutter-Text 以字符的方式截断
Text 以字符的方式截断 https://github.com/flutter/flutter/issues/52869 在flutter中,Text控件默认的溢出显示模式是TextOverflow.fade ,就是淡出 在iOS或者Android平台默认的文件截断模式一般是…省略,flutter里面对应的截断模式为TextOverflow.ellipsis ,不过这里的截断是英文按照单词来的,这样的模式会导致如果最后一个单词很长时,截断显示会整理省略而不是最后超出的字符省略,导致模块可能有一大块空白。
10 0
数字科技陪伴企业成长,华米再造“华米”
连环创业,年少有名。在互联网界,华米的黄汪是个传奇。“可穿戴设备巨头环伺之下,华米凭什么立足?”
12 0
小程序的开发之使用SVG
昨天突然提出要在小程序中使用SVG,因为我们的小程序项目是有主题色的。不同的主题色时有些图片一直是固定的,显的有些格格不入,所以打算使用SVG来实现根据主题色的颜色进行变化。
17 0
手机进化论:4天线引领下一波终端创新
手机进化论:4天线引领下一波终端创新
7 0
用代码“读懂”代码:衡量开发交付质量(微服务度量之一)
用代码“读懂”代码:衡量开发交付质量(微服务度量之一)
6 0
flutter - URL出现在网站名称的位置
flutter - URL出现在网站名称的位置 从Android Studio运行时:
9 0
数据之争加速速AI时代合纵连横时代到来
数据之争加速速AI时代合纵连横时代到来
8 0
+关注
20382
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载