文档章节

PullToRefresh的学习研究(三)---子类们

j
 jscoolstar
发布于 2015/06/17 16:21
字数 2029
阅读 48
收藏 0
点赞 0
评论 0

子类有多个,先从最常用最关注的说起吧。

1、public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extends PullToRefreshBase<T>

首先有这么一个成员变量:/**
     * TODO 提示器,比如滑动顶部的时候渐显出来,告诉用户这个位置可以下拉刷新了
     * @Auther : shenqichao
     * @Date:2015年6月17日 上午11:14:27
     */
    private IndicatorLayout mIndicatorIvTop;
    private IndicatorLayout mIndicatorIvBottom;

private OnScrollListener mOnScrollListener;这里定义了一个滑动监听,这其实是供给用户处理滑动事件的,它本身不处理刷新相关的逻辑,因为在构造里面有这么一句:public PullToRefreshAdapterViewBase(Context context) {
        super(context);
        mRefreshableView.setOnScrollListener(this);
    }

自己的refreshableView的滑动监听其实是子类自己,而在对应的各个接口函数里都会调用mOnScrollListener.do,比如:public final void onScrollStateChanged(final AbsListView view, final int state) {
        /**
         * Check that the scrolling has stopped, and that the last item is
         * visible.
         */
        if (state == OnScrollListener.SCROLL_STATE_IDLE && null != mOnLastItemVisibleListener && mLastItemVisible) {
            mOnLastItemVisibleListener.onLastItemVisible();
        }

        if (null != mOnScrollListener) {
            mOnScrollListener.onScrollStateChanged(view, state);
        }
    }

下面是子类核心功能作用,(指示器只是添花的作用,不要也不影响)

protected boolean isReadyForPullStart() {
        return isFirstItemVisible();
    }

    protected boolean isReadyForPullEnd() {
        return isLastItemVisible();
    }

先看第一个,是否准备好顶部下拉刷新了?return的是isFirstItemVisible();,虽然名字是这样起的,但是其方法内部并不是判断的仅仅是是否visiable。

private boolean isFirstItemVisible() {
        final Adapter adapter = mRefreshableView.getAdapter();

        if (null == adapter || adapter.isEmpty()) {
            if (DEBUG) {
                Log.d(LOG_TAG, "isFirstItemVisible. Empty View.");
            }
            return true;

        } else {

            /**
             * This check should really just be:
             * mRefreshableView.getFirstVisiblePosition() == 0, but PtRListView
             * internally use a HeaderView which messes the positions up. For
             * now we'll just add one to account for it and rely on the inner
             * condition which checks getTop().
             */
            if (mRefreshableView.getFirstVisiblePosition() <= 1) {
                final View firstVisibleChild = mRefreshableView.getChildAt(0);
                if (firstVisibleChild != null) {
                    return firstVisibleChild.getTop() >= mRefreshableView.getTop();
                }
            }
        }

        return false;
    }

代码解决了第一篇的一个疑问,即listview加了自己header之后是否还可用。这里可以看到代码是可用的。首先 if (mRefreshableView.getFirstVisiblePosition() <= 1) {感觉这里的代码有点累赘了,可能是sdk版本的问题?这里其实确实可以只用getFirstVisiblePosition()==0来判断的,在==0的时候,在获取getChildAt(0),去获取他的getTop和listview本身的gettop对比),写到这里的时候卡壳了,我研究了很久为什么作者要写成<=1,我自己做了个实验,用了个普通的listview,自己加了个header,有header的时候,就显示Header是0,没有就第一个元素是0,所以不管怎样我都觉得滑动要判断第0个,所以觉得作者不用写成<=1。但是我运行demo的代码,有header的时候getFirstVisiblePosition()=1,没header的时候也显示1,整的我特别的莫名其妙.由于马虎看了好久代码也没找到原因,后来~~~我终于明白了,什么是哎。。

PullToRefreshListView继承adpterview,

@Override
    protected void handleStyledAttributes(TypedArray a) {
        super.handleStyledAttributes(a);

        mListViewExtrasEnabled = a.getBoolean(R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true);

        if (mListViewExtrasEnabled) {
            final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL);

            // Create Loading Views ready for use later
            FrameLayout frame = new FrameLayout(getContext());
            mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a);
            mHeaderLoadingView.setVisibility(View.GONE);
            frame.addView(mHeaderLoadingView, lp);
            mRefreshableView.addHeaderView(frame, null, false);

            mLvFooterLoadingFrame = new FrameLayout(getContext());
            mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a);
            mFooterLoadingView.setVisibility(View.GONE);
            mLvFooterLoadingFrame.addView(mFooterLoadingView, lp);

            /**
             * If the value for Scrolling While Refreshing hasn't been
             * explicitly set via XML, enable Scrolling While Refreshing.
             */
            if (!a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {
                setScrollingWhileRefreshingEnabled(true);
            }
        }
    }这里是基类留给所有子类来处理自己的attr的, mListViewExtrasEnabled = a.getBoolean(R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true);这行代码很长。。在写博客,并且要在模拟器上测试,所以eclipse不是最大化,这行代码没显示全,我理解的意思是listview是否可以扩展,即分组。所以认为取这属性时默认应该是false的。所以也就不会执行false里面的东西。。。但是我错了,小裤裤都错掉了。这个if里面加了mHeaderLoadingView,是真正意义上的加了。。。但是还设置成了visiable=gone,然后就出现了怪现象,第零个item总打印成他是第一个。然后我继续围绕代码和运行时的表现,发现mListViewExtrasEnabled这个字段不是代表分组的情况。而是当freshing的时候,listview是否可以滑动。当我实验完这个字段之后我又记起基类里有这个字段mScrollingWhileRefreshingEnabled,我就在想他们俩不是一个意思吗?然后又开始换状态运行发现了一个问题。mScrollingWhileRefreshingEnabled这个确实也是代表freshing的时候view是否可滑动。如果是false,那刷新的时候在基类的touch拦截那里就拦截了,所以也就无法滑动freshableview了。如果设置成true,就可以滑动,但是lsitview的体验是,他自己可以滑动,但是上面的head加载条却一直显示着,因为继承的LinearLayout,而且代码发现mScrollingWhileRefreshingEnabled这个是true的时候,在touch事件里面并没有处理scrollto来改变listview和header的滑动关系,比如代码处理的原理就是header位置不变,显示刷新中的状态,listview在“header”的下面可以上下滑动,说白了就是listview没有全屏,在下面的区域展示着自己。如果想做复杂点,我觉得应该在touch里面scrollto来改变header的位置,当达到临界值时,再不拦截touch,再交给freshableview去执行,这样就能实现listview和加载的header同时上移的视觉。mListViewExtrasEnabled这个属性,其实也是代表freshing的时候是否可以滑动。但是它作为一个单独出来的变量,仅仅是为了Listview自己的方便,这个属性默认为true,true的时候,会add一个真正的header,然后gone掉,当freshing的时候,他会把基类的headlayout隐藏掉,然后显示自己的header,并调用header的.freshing方法。当fresh完成,它再gone掉,然后显示基类的loadinglayout。。我觉得需要优化。抱着试试看的态度,我把gridview的demo设置成了刷新时可滑动属性,嗯,不好看。因为gridview不能加header。所以只能是第一种表现形式,而且发现一个UIbug:demo中是空的gridview,下拉刷行过程中,原来是不能滑动的,设置成可以滑动之后,因为gridview的是空的,lastvisiableitem自然是空的,所以你刚刚执行了下拉刷新后,马上往上提,底部会出现加载更多的footer,当然作者的代码逻辑只会让UI显示出来,却不会加载更多。但我觉得,加载更多也不该显示,同理,当加载更多的时候,也不应该下拉显示刷新的按钮,都应该等fresh结束之后,再去决定用户的操作是想下拉还是上拉。

好了,基本到这里了,listview竟然还是所有子类里面最复杂的一个。其他的几个都可以根据各自的特色来实现基类的abstract方法。比如webview,可以根据自己的contentheight属性(当然查了下api只有这个,没有contentwidth属性,也就意味着webview是不能左拉刷新的。。。)scollview就是根据getScrollY来判断。总之就是实现基类的@Override
    protected boolean isReadyForPullStart()
    protected boolean isReadyForPullEnd()

这两个方法,你甚至可以把方法内部写成滑动一半就刷新,只要你的子类告诉基类,我现在处于ready状态,基类再结合其他属性比如当前是“向上”还是“向下”滑动?等来决定现在要不要显示出LoadingLayout.

另外就是几个子类都根据api级别来构建listview/webview等等。因为api大于9的都有一个overScroll方法,通过OverScrollHelper来重新这个方法以达到更好的过量滑动视觉效果,如果api没有大于9,是无所谓了。


后记:listview里面有这样一句if (!a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {
                setScrollingWhileRefreshingEnabled(true);
            },当mListViewExtrasEnabled为true时,它会找xml配置,如果不存在那个属性配置就配置为true,这样mListViewExtrasEnabled才能生效,否则即使mListViewExtrasEnabled是true,如果xml明确配置ptrScrollingWhileRefreshingEnabled为false,那么也无法在freshing的时候滑动。看看能否优化成不使用mListViewExtrasEnabled,理论上所有的UI当下拉更新时,如果可以滑动,都应该带着顶部的loading一起滑动,不能因为只有listview有header所以有这样好的表现形式,而其他几个view就无法拥有这样的展现形式。


© 著作权归作者所有

共有 人打赏支持
j
粉丝 0
博文 3
码字总数 6889
作品 0
海淀
程序员
智能卡开发的相关总结

1.EMV技术学习和研究(一)开篇(http://blog.csdn.net/xuture/article/details/9208259) 2.EMV技术学习和研究(二)应用选择(http://blog.csdn.net/xuture/article/details/9250067) 3.EMV技......

IT追寻者 ⋅ 2016/09/08 ⋅ 0

学习东西总结:

一.JAVA 基础 1、JAVA并发编程 2.JAVA NIO系列 3.JVM深入了解 4.JAVA性能优化相关研究 5.JAVA7,8新特性 二、数据库 1.数据库优化研究 2.MYSQL高可用性研究 3.MYSQL源码研究 三、网络 1.HTTP...

QH_C ⋅ 2016/03/25 ⋅ 0

java EnumSet学习

一、EnumSet 简单介绍 二、EnumSet的内部设计思路 EnumSet是一个抽象类,内部多处采用静态工厂方法。它不对外提供构造函数,只能通过一系列静态方法,如of(...)、noneOf(...)、copyOf(...)、...

undefined可以吗 ⋅ 01/13 ⋅ 0

腾讯 AI Lab 主任张潼博士:机器学习里的优化问题

雷锋网 AI 科技评论按,日前,在由上海财经大学交叉科学研究院(RIIS)主办,杉数科技有限公司协办的「现代运筹学发展讨论会」上,腾讯 AI Lab(腾讯人工智能实验室)主任张潼博士发表了精彩...

思颖 ⋅ 01/10 ⋅ 0

Android-PullToRefresh使用

接上篇,很多人看到有好源码,但是在使用时碰到了问题。在此简单介绍一下,希望能够对那些不会的童鞋们有所帮助。 首先下载源码,源码地址:https://github.com/chrisbanes/Android-PullToR...

崔同亮 ⋅ 2013/10/23 ⋅ 0

荐会 | CoRL:机器人与机器学习领域的下一个顶级会议

作为当前炙手可热的研究领域,人工智能的发展可以用“日新月异”来形容。与此相对应的是,尽管目前已经有着诸多人工智能相关的学术会议,但这些学术会议或许过于大而全和不能很好体现出这一领...

岑大师 ⋅ 2017/11/14 ⋅ 0

【政策】北京市科委发布最新征集新一代人工智能、脑认知与类脑技术等六大领域储备课题

去年,在国家层面频频出台一系列人工智能发展规划政策后,2018年地方进入政策落地实施阶段。 11日,北京市科委发布六份通知,征集2018年六大技术领域储备课题,这六大领域分别为: ①认知与类...

技术小能手 ⋅ 01/12 ⋅ 0

这些人你还不认识?!一文带你有姿势地侃深度学习大佬

大数据文摘作品 编译:余志文,笪洁琼,钱天培 近几年间,深度学习的兴起造就了一批超级巨星。一向在学术界默默无闻的大佬们,相继成为了业界的领头人,而他们的声名也再从业界一路传至大众耳...

uwr44uouqcnsuqb60zk2 ⋅ 2017/11/03 ⋅ 0

京东和斯坦福达成合作 共同推进AI研究

中关村在线消息:美国当地时间11月27日,京东与斯坦福大学人工智能实验室正式达成战略合作关系,启动了京东-斯坦福大学联合人工智能研究计划。此后,京东将会与斯坦福大学人工智能实验室围绕...

张泓杨 ⋅ 2017/11/30 ⋅ 0

Android SDK示例代码学习(1)----BouncingBalls

最近在学习android的开发,打算把sdk的示例代码研究一下,一直以来都没有做笔记的习惯,以至于看过的东西记住的少遗忘的多,因此试试记下笔记,以备以后查询。 ----------------------------...

开开904 ⋅ 2014/03/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Day 17 vim简介与一般模式介绍

vim简介 vi和Vim的最大区别就是编辑一个文件时vi不会显示颜色,而Vim会显示颜色。显示颜色更便于用户编辑,凄然功能没有太大的区别 使用 yum install -y vim-enhanced 安装 vim的三种常用模式...

杉下 ⋅ 52分钟前 ⋅ 0

【每天一个JQuery特效】根据可见状态确定是否显示或隐藏元素(3)

效果图示: 主要代码: <!DOCTYPE html><html><head><meta charset="UTF-8"><title>根据可见状态确定 是否显示或隐藏元素</title><script src="js/jquery-3.3.1.min.js" ty......

Rhymo-Wu ⋅ 今天 ⋅ 0

OSChina 周四乱弹 —— 初中我身体就已经垮了,不知道为什么

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @加油东溪少年 :下完这场雨 后弦 《下完这场雨》- 后弦 手机党少年们想听歌,请使劲儿戳(这里) @马丁的代码 :买了日本 日本果然赢了 翻了...

小小编辑 ⋅ 今天 ⋅ 12

浅谈springboot Web模式下的线程安全问题

我们在@RestController下,一般都是@AutoWired一些Service,由于这些Service都是单例,所以并不存在线程安全问题。 由于Controller本身是单例模式 (非线程安全的), 这意味着每个request过来,...

算法之名 ⋅ 今天 ⋅ 0

知乎Java数据结构

作者:匿名用户 链接:https://www.zhihu.com/question/35947829/answer/66113038 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 感觉知乎上嘲讽题主简...

颖伙虫 ⋅ 今天 ⋅ 0

Confluence 6 恢复一个站点有关使用站点导出为备份的说明

推荐使用生产备份策略。我们推荐你针对你的生产环境中使用的 Confluence 参考 Production Backup Strategy 页面中的内容进行备份和恢复(这个需要你备份你的数据库和 home 目录)。XML 导出备...

honeymose ⋅ 今天 ⋅ 0

JavaScript零基础入门——(九)JavaScript的函数

JavaScript零基础入门——(九)JavaScript的函数 欢迎回到我们的JavaScript零基础入门,上一节课我们了解了有关JS中数组的相关知识点,不知道大家有没有自己去敲一敲,消化一下?这一节课,...

JandenMa ⋅ 今天 ⋅ 0

火狐浏览器各版本下载及插件httprequest

各版本下载地址:http://ftp.mozilla.org/pub/mozilla.org//firefox/releases/ httprequest插件截至57版本可用

xiaoge2016 ⋅ 今天 ⋅ 0

Docker系列教程28-实战:使用Docker Compose运行ELK

原文:http://www.itmuch.com/docker/28-docker-compose-in-action-elk/,转载请说明出处。 ElasticSearch【存储】 Logtash【日志聚合器】 Kibana【界面】 答案: version: '2'services: ...

周立_ITMuch ⋅ 今天 ⋅ 0

使用快嘉sdkg极速搭建接口模拟系统

在具体项目研发过程中,一旦前后端双方约定好接口,前端和app同事就会希望后台同事可以尽快提供可供对接的接口方便调试,而对后台同事来说定好接口还仅是个开始、设计流程,实现业务逻辑,编...

fastjrun ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部