自个儿写Android的下拉刷新/上拉加载控件

Android实现RecyclerView的下拉刷新和上拉加载更多 需求先上效果图, Material Design风格的下拉刷新和上拉加载更多。 源码地址(欢迎star) https://github.com/studychen/SeeNewsV2如果对于RecyclerView还不熟悉,参见这篇 Android Material Design学习之RecyclerView代替 ListView下拉刷新效果图上拉时候会有一个圆形动画,刷新加载数据。思路使用Goog 阅读详情

前段时间自己写了一个能够“通用”的,支持下拉刷新和上拉加载的自定义控件。可能现如今这已经不新鲜了,但有兴趣的朋友还是可以一起来看看的。

  • 与通常的View配合使用(比如ImageView)

ImageView下拉刷新

  • 与ListView配合使用

ListView下拉刷新、上拉加载

  • 与RecyclerView配合使用

RecyclerView下拉刷新、上拉加载

  • 与SrcollView配合使用

SrcollView下拉刷新

  • 局部刷新(但想必这种需要实际应该还是不多的….)

作为局部View刷新

好啦,效果大概就是这样。如果您看后觉得有一点兴趣。那么,以下是相关的信息:


好了,闲话就到这里了。现在正式切入正题,于此逐步简单的记录和总结一下实现这个自定义View的思路以及实现过程。

首先,我们分析一下:假设我们现在的需求是需要让ListView支持下拉刷新和上拉加载,那么其实我们选择去扩展系统自身的ListView是最好的。
但我们这里的初衷是创造一个通用的Pullable的控件,也就是说它可以配合Android中各种View使用。所以,显然我们需要的是一个ViewGroup。
那么,既然有了思路就可以开动了:第一步我们先去创建我们自己的View,并让其继承自ViewGroup。例如就像下面这样:

public class PullableLayout extends ViewGroup{

    public PullableLayout(Context context) {
        super(context);
    }

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

接下来,我们静静的思考一下所谓的下拉刷新,上拉加载的本质何如。就会发现,其实归根结底原理仍旧是“视图的滚动”而已。
那么,我们来分析下我们为什么会这么说呢?假设现在先在脑海中简单构画一下如下所示的这样一个ViewGroup的结构图:

假设上图中蓝色的部分就是屏幕区域,也就是我们想要呈现内容的区域(比如我们在这里放一个ListView)。而我们的ViewGroup所需要做的工作就是:
为Content部分加上一个Header(头视图)与Footer(尾视图),并且显然Header的位置应该位于Content之上,同理Footer则位于其之下。

那么,在这个基础上,如果我们让整个Viewgroup支持滚动,那么就得以实现一种效果了,即:初始情况下,屏幕上将正常呈现我们的Content视图。
与此同时:当我们上下滑动屏幕,那么当滑动到Content视图的顶部时,就会出现Header视图;当滑动到Content的底部时,则会出现Footer视图。

当然,这种纸上谈兵式的原理性的东西,永远都让人感到无聊。所以,现在我们实际的来“兑换”一下我们目前为止谈到的这种效果。看以下布局文件:

左边的布局非常简单和熟悉,就是显示一个宽高填满父窗口的ImageView。而在右边我们则是把父布局替换成了我们自定义的PullableLayout。

好的,现在我们就一起来看看,我们应该怎么样逐步完善PullableLayout让它实现我们说到的效果。
首先,既然我们说到需要一个Header与Footer。那么,我们就先来定义好这两个东东的布局。比如说,我们定义一个如下的Header布局:

这个布局还是非常简单明了的。同样的,Footer布局的定义其实与Header是非常类似的,所以就不再贴一次代码了。
准备好Header与Footer布局后,我们应该考虑的工作,就是怎么把它们按照我们的需要给“放进”我们自己的PullableLayout当中了,其实这并不难。

private View mHeader,mFooter;

    public PullableLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mHeader = LayoutInflater.from(context).inflate(R.layout.header_pullable_layout,null);
        mFooter = LayoutInflater.from(context).inflate(R.layout.footer_pullable_layout,null);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        // 看这里哦,亲
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams
                (RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);
        mHeader.setLayoutParams(params);
        mFooter.setLayoutParams(params);
        addView(mHeader);
        addView(mFooter);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 测量
        for (int i = 0; i < getChildCount(); i++){
            View child = getChildAt(i);
            measureChild(child,widthMeasureSpec,heightMeasureSpec);
        }
    }

    private int mLayoutContentHeight;
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        mLayoutContentHeight = 0;
        // 置位
        for (int i = 0; i < getChildCount(); i++){
            View child = getChildAt(i);
            if (child == mHeader) { // 头视图隐藏在顶端
                child.layout(0, 0 - child.getMeasuredHeight(), child.getMeasuredWidth(), 0);
            } else if (child == mFooter) { // 尾视图隐藏在layout所有内容视图之后
                child.layout(0, mLayoutContentHeight, child.getMeasuredWidth(), mLayoutContentHeight + child.getMeasuredHeight());
            } else { // 内容视图根据定义(插入)顺序,按由上到下的顺序在垂直方向进行排列
                child.layout(0, mLayoutContentHeight, child.getMeasuredWidth(), mLayoutContentHeight + child.getMeasuredHeight());
                mLayoutContentHeight += child.getMeasuredHeight();
            }
        }
    }

以上的代码也并不复杂,核心的工作就是填充Header与Footer视图,并且按需要进行测量和置位的工作。如果作为新手来说,值得注意的可能就是:

  • Header与Footer的addView()工作:如果放在Constructor中,那么因为此时布局文件中的内容都还未进行装载和填充,就可能会在后续的代码中因为某些代码逻辑出现意料之外的异常错误;而如果放在onMeasure,则会因为onMeasure的内部机制造成重复add。所以放在onFinishInflate算是一个比较合适的选择。

  • 个人在这里定义了一个变量mLayoutContentHeight用来记录内容视图部分的实际总高度。需要注意的是,要在onLayout开头的地方将其置零,否则同样会因为重复累加得到错误的结果。

现在,当我们运行程序,就会在屏幕上呈现一个宽高占满屏幕的图片。目前看起来是与把ImageView放在其它常用的Layout中的效果是没有区别的。

所以,显然我们接下来要做的工作就是让视图能够跟随着我们的手指滚动起来。那么,还有什么好想的呢?自然就是覆写onTouchEvent了。

  private int mLastMoveY;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int y = (int) event.getY();

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mLastMoveY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int dy = mLastMoveY - y;
                scrollBy(0, dy);
                break;
        }

        mLastMoveY = y;
        return true;
    }

我们看到现在似乎已经有点意思了,但其实显然是远远不够的。现在说穿了就只是一个支持滚动的视图而已,看上去非常呆板,更别提下拉刷新此类了。

那么,我们想一下应该怎么改进呢?有了,我们可以给每次的拉动设置一些相关信息,比如“最大滚动距离,有效距离”等等。这是什么意思呢?
打个比方:当拉动的距离超过了最大距离,我们就不允许视图继续滚动了;而当此次拉动的距离超过有效距离我们就认为这是一次有效的行为。
那么现在我们先做点小改进,当拉动的距离超过有效距离,我们就将文字信息改为“松开刷新”,以提示用户你现在松开手指就会执行刷新的行为了。

            case MotionEvent.ACTION_MOVE:
                int dy = mLastMoveY - y;
                // dy < 0代表是针对下拉刷新的操作
                if(dy < 0) {
                    if(Math.abs(getScrollY()) <= mHeader.getMeasuredHeight() / 2) {
                        scrollBy(0, dy);
                        if(Math.abs(getScrollY()) >= effectiveScrollY){
                            tvPullHeader.setText("松开刷新");
                        }
                    }
                }
                break;

这里我们所做的改动实际就是:当进行下拉操作的时候,如果下拉距离已经达到header的一半高度,就不允许继续下拉了。
同时来说,如果当我们的拉动行为超过了有效距离effectiveScrollY,就提示用户可以“松开刷新”了。同样的,看看效果如何:

显然,我们又向前迈进了小小的一步。但最终的效果依旧有些呆板。因为虽然提示了可以“松开刷新”,但现在即使我们松开,也不会有任何效果。
松开手指却没有对应效果,显然是因为我们还没有在Action_Up的时候做对应的操作,那么现在就来进一步的修改吧:

            case MotionEvent.ACTION_UP:
                if(Math.abs(getScrollY()) >= effectiveScrollY){
                    mLayoutScroller.startScroll(0, getScrollY(), 0, -(getScrollY() + effectiveScrollY));
                    tvPullHeader.setVisibility(View.GONE);
                    pbPullHeader.setVisibility(View.VISIBLE);
                }else{
                    mLayoutScroller.startScroll(0, getScrollY(), 0, -getScrollY());
                }
                break;

因为仅仅是为了说明原理,所以这一步的改动代码也非常的简单。简单来说就是:如果松开手指时,滑动的距离并未超过有效距离,我们就认为这并不是一次成功有效的刷新行为,那么让view的位置变动恢复就行了。而如果手指离开时,已经滑动超过了有效驱离,则将view滑动到刚好能够让Header显示出有效距离的部分的位置,来提示用户正处于刷新的状态下。对应下面的效果图就更容易理解我们所做的工作是什么了:

让人高兴的是,到了这里看上去效果就很不错了。但虽然效果是有了,看上去像是在刷新,实际却没有执行任何实际用于刷新的操作。
所以说,显然我们还需要提供一个回调接口,让client端在使用的时候能够顺利在合适的时机执行需要的操作(刷新/加载)。

 public interface onRefreshListener{
        void onRefresh();
    }

    private onRefreshListener mRefreshListener;

    public void setRefreshListener(onRefreshListener listener){
        mRefreshListener = listener;
    }

    public void refreshDone(){
        mLayoutScroller.startScroll(0, getScrollY(), 0, -getScrollY());
        pbPullHeader.setVisibility(View.GONE);
        tvPullHeader.setText("继续向下拉");
        tvPullHeader.setVisibility(View.VISIBLE);
    }

case MotionEvent.ACTION_UP:
if(Math.abs(getScrollY()) >= effectiveScrollY){
   // 省略之前的代码......

   // 执行回调
   mRefreshListener.onRefresh();
}else{
   mLayoutScroller.startScroll(0, getScrollY(), 0, -getScrollY());
}
break;

public class MainActivity extends AppCompatActivity {
    private PullableLayout plMain;
    private ImageView iv;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            iv.setBackgroundResource(R.drawable.ace);
            plMain.refreshDone();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        iv = (ImageView) findViewById(R.id.iv);
        plMain = (PullableLayout) findViewById(R.id.pl_main);
        plMain.setRefreshListener(new PullableLayout.onRefreshListener() {
            @Override
            public void onRefresh() {
                 new Thread(new Runnable() {
                     @Override
                     public void run() {
                         try {
                             Thread.sleep(3000);
                         } catch (InterruptedException e) {
                             e.printStackTrace();
                         }

                         mHandler.sendEmptyMessage(0);
                     }
                 }).start();
            }
        });
    }
}

OK,大功告成,现在我们在来看一看效果如何:

可以看到,到这里我们就已经完全实现了“下拉刷新”这一功能了。当然这里只是为了演示原理的demo,所以很多代码都没有那么的追求严谨。
当然,这里要总结的重点其实也只是个人的思路和实现原理而已。所以同理,只要理解了这种思路,“上拉加载”也同样就能够实现了,故不再赘述。

那么,是不是到了这里,我们就可以结束了呢?当然不是,因为之前我们说过需要让我们的PullableLayout是通用的。而以目前来说:
我们绝大多数普通的常用控件,是能够通用的。但是呢?对另一类以ListView,GridView,RecyclerView,ScrollView为代表的控件就不灵了。
显然,这类控件与普通的View相比,最大的特点就是:它们自身就是支持滚动的。所以无法避免的,就会与我们的控件出现“滑动冲突”。

那么,关于“滑动冲突”的解决方案,可以参考《Android开发艺术探索》,作者针对各种常见的滑动冲突都给出了非常实用的干货方案。
OK,这里我们假设以ListView与我们自定义的Layout配合使用为例。那么出现的滑动冲突就是,双方都需要处理上下滑动的行为。
《Android开发艺术探索》中已经说过,这种冲突往往都可以从业务逻辑上找到突破口。那么,我们来思考一下这个所谓的“突破口”:
显然,如果我们的ListView需要下拉刷新或者上拉加载,那么刷新行为的发生时机就是在ListView的内容已经到达最现有的最顶部时,再继续下拉。
同理,加载的行为发生的时机就是内容已经到达最现有的最底部时,继续上拉。所以,如此一分析,这个突破口就已经出现了:
以下拉行为为例,我们就应该在ListView未到达顶部的情况下,将滑动事件交给ListView处理。而如果已经到达顶部,就将事件拦截,自己处理。

现在我们的思路已经明确了,接着要做的,自然就是将思路转化到代码上面了。其实,所谓的“滑动冲突”的处理,最终实际就是回归到在ViewGroup的onInterceptTouchEvent方法上根据业务逻辑处理事件的拦截。对应我们这里的需求来说,以ListView的下拉操作为例,就可以这样做:

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {

        boolean intercept = false;
        // 记录此次触摸事件的y坐标
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                intercept = false;
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                if (y > mLastMoveY) { // 下滑操作
                    View child = getChildAt(0);
                    if (child instanceof AdapterView) {
                        AdapterView adapterChild = (AdapterView) child;
                        // 判断AbsListView是否已经到达内容最顶部(如果已经到达最顶部,就拦截事件,自己处理滑动)
                        if (adapterChild.getFirstVisiblePosition() == 0
                                || adapterChild.getChildAt(0).getTop() == 0) {
                            intercept = true;
                        }
                    }
                }

                break;
            }
            // Up事件
            case MotionEvent.ACTION_UP: {
                intercept = false;
                break;
            }
        }

        mLastMoveY = y;
        return intercept;
    }

好了,差不多就是这样了。再次说明这里主要旨在总结和分享一下个人对于此类需求的实现思路。当然大家可能会有更加优秀的实现方式,请多多指教!
另外,也可能有朋友注意到在最初的演示图中,使用了两个比较有趣的Loading动画。一个是下拉时的小幽灵,一个时上拉时的吃豆子的形象。
同样再次申明:这两种效果都来自Github上一位作者开源的库:https://github.com/ldoublem/LoadingView,里面有很多有意思的Loading效果。
个人而言,对那个小幽灵的形象比较有兴趣,所以也简单研究了下作者的源码。如果您也有兴趣,那也可以看一看我之前写的:用Canvas和属性动画造一只萌蠢的“小鬼”。

MaterialRefreshLayout实现下拉刷新上拉加载更多 通过本文可以了解以下几方面: 1、MaterialRefreshLayout是什么 2、MaterialRefreshLayout怎么使用 3、一个简单的小小demo带你实现下拉刷新上拉加载更多 阅读详情

相关推荐

android自定义下拉刷新和上拉加载控件

前段时间和同事一起写了一个下拉刷新和上拉加载的控件。该控件实现的功能的功能还是挺多的。支持自定义头部和底布局,同时还处理了NestScrolling机制的嵌套滑动的一些东西。我们先来看下效果图吧。 1.主页面布局展示 2.支持RecycleView的刷新和加载效果。 3.支持listView的刷新和加载效果。 4.支持ScrollView的刷新和加载效果 5.支持NestScrollin

qq_23874081的专栏 1788

【Android】下拉刷新&上拉加载更多组件记录(81/100)

第81个

产品:SmartApi;服务:大前端++;其他技术分享 1627

从高德、百度地图下载POI数据?用这个工具5分钟搞定GCJ02/BD09到WGS84的坐标纠偏

本文详细解析了高德、百度地图POI数据坐标偏移问题,并提供了从GCJ02/BD09到WGS84的高效转换方案。通过开源工具如coordtransform和ArcGIS等专业软件,实现毫米级精度的坐标纠偏,适用于商业选址、GIS分析等场景,显著提升数据准确性和工作效率。

weixin_26789847的博客 448

Android下拉刷新和上拉加载更多

Android下拉刷新和上拉加载更多 下拉刷新 通过android系统提供的组件:SwipeRefreshLayout 一、基本使用 1 xml中 添加 SwipeRefreshLayout 组件 该组件包含着要操作下拉刷新的控件 如ListView RecyclerView 等 注意这里的SwipeRefreshLayout组件的子布局只能有一个 &lt;androi...

5ingwings(SiHao)的博客 2万+

ARS408毫米波雷达数据解析避坑指南:从硬件连接到Python处理

本文提供了ARS408毫米波雷达从硬件连接到Python数据处理的完整实战指南。针对串口通信不稳定、数据解析错误等常见问题,详细解析了硬件连接方案选择、串口数据高效读取策略、二进制协议解析的位操作技巧,并给出了坐标转换、目标跟踪及实时可视化的代码实现,帮助开发者快速搭建稳定的雷达数据处理流水线。

weixin_29091105的博客 149

基于RTL8370N的8口千兆无管理交换机硬件设计

无管理交换机是局域网边缘接入的核心基础设备,其本质是通过硬件状态机实现MAC地址学习、线速转发与自动协商,无需软件配置即可完成即插即用组网。原理上依赖高度集成的PHY+交换矩阵单芯片(如RTL8370N),结合确定性硬件逻辑替代MCU固件,保障低延迟、高可靠与零运维。技术价值体现在成本压缩、体积精简与部署极简化,广泛应用于家庭网络扩展、工业现场设备联网及嵌入式系统桥接等场景。本文详解一款基于RTL8370N的紧凑型8端口千兆无管理交换机,覆盖芯片选型依据、PHY接口设计、电源与散热优化等关键工程实践。

weixin_42327217的博客 399

Android中的RecyclerView下拉/上拉刷新数据

RecyclerView上拉/下拉刷新数据

m0_62278064的博客 5459

Godot 2D游戏开发实战:用GDScript复刻10款经典小游戏(附完整源码)

本文是一份Godot 2D游戏开发实战指南,通过使用GDScript语言复刻10款经典小游戏,帮助开发者快速掌握引擎核心功能。内容涵盖从环境配置、GDScript基础到贪吃蛇、Flappy Bird、打砖块、俄罗斯方块等项目的核心逻辑与代码实现,并附有完整源码,旨在通过实践提升独立开发能力。

gold的博客 778

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9255575 最近项目中需要用到ListView下拉刷新的功能,一开始想图省事,在网上直接找一个现成的,可是尝试了网上多个版本的下拉刷新之后发现效果都不怎么理想。有些是因为功能不完整或有Bug,有些是因为使用起来太复杂,十全十美的还真没找到。因此我也是放弃了在网上找现成代码的想法,...

runfeel 4980

Ovito隐藏技巧:用Expression Selection快速提取分子链(附模糊背景配置参数)

本文详细介绍了Ovito软件中Expression Selection功能的隐藏技巧,用于从复杂的分子动力学模拟数据中快速、精准地提取目标分子链。通过结合Expand Selection和Invert Selection等修饰器,形成一套高效的工作流,并深入解析了实现SCI论文级渲染效果的景深模糊参数配置,帮助研究者大幅提升数据处理与图片生成效率。

pz890123的博客 867

Altium Designer(AD)的简易使用

一、绘制原理图、原理图库 首先来说明原理图的概念。 根据百度百科,原理图,顾名思义就是表示电路板上各器件之间连接原理的图表。也就是表示芯片上的引脚连接什么元件,各个元件谁和谁相连,电源电压的大小之类的。​ 再来说一下原理图和原理图库的区别和联系。 原理图是某个产品的原理图设计文件;原理图库是设计原理图时用到的电子元件的电路符号的集合。绘制PCB板时先设计原理图即建立原理图文件,而在原理图文件中设计原理图前必须将原理图库文件加载到原理图编辑环境才能使用其中的电路符号。 接下来说明如...

qq_52630607的博客 2万+

自个儿写Android的下拉刷新/上拉加载控件 (续)

本文算是对之前的一篇博文《自个儿写Android的下拉刷新/上拉加载控件》的续章,如果有兴趣了解更多的朋友可以先看一看之前的这篇博客。事实上之所以会有之前的那篇博文的出现,是起因于前段时间自己在写一个练手的App时很快就遇到这种需求。其实我们可以发现类似这样下拉刷新、上拉加载的功能正在变得越来越普遍,可以说如今基本上绝大多数的应用里面都会使用到。当然,随着Android的发展,已经有不少现成的可以实

LaterEqualsNever 3713

【5G演进】4G到5G演进之网络架构与协议栈

4G到5G演进之网络架构与协议栈

Learning makes me happy (0^◇^0) 5529

Android实现下拉刷新和上拉加载数据(网络请求数据)

在安卓开发中,我们会经常遇到上拉加载和下拉刷新的功能,通过网络请求拿到数据然后添加到控件上,之前自己也在网上搜索过一些文章,但基本上用处不大,要么是效果不一样,要么是贴的代码不完整,从而导致功能无法正常使用(很蛋疼),所以在摸索了一阵之后,完成了一个大致OK的demo,供大家参考。有问题还望大家指正出来,感激不尽。。 ......

小口口的博客 1万+

【文献笔记】ICCV 2021 | Point Transformer

作者提到,特别适合点云处理,因为自注意力机制是的核心,本质上就是一个集合算子:它对输入元素具有顺序不变性和数量不变性3D点云是无序的,即使改变点云txt文件中的点顺序也不会有任何影响。自注意力机制天然具有排列不变性,因为它通过对所有"点对"的关系进行建模来处理输入,而不依赖于任何特定的输入顺序点云数据通常覆盖了3D空间中的对象或场景,理解这些数据需要捕捉点与点之间复杂的空间关系。自注意力机制能够有效的捕捉这些关系,因为它为每个"点对"赋予一个。

m0_55908255的博客 965

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

下拉刷新、上拉加载更多控件实现原理及解析(一)

以前那个账号,以后可能不用了,把文章搬过来!!!效果预览接受hi大头鬼hi的建议,来一个动态图,方便大家知道这是个什么东西。动机项目中,需要一个支持任意View的下拉刷新+上拉加载控件,GitHub上有很多现成的实现,如Android-PullToRefresh, android-Ultra-Pull-To-Refresh等,这些Library都非常优秀,但是Android-PullToRefres

老萌主的博客 3455

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Android下拉刷新上拉加载控件,对所有View通用!

前面写过一篇关于下拉刷新控件的博客下拉刷新控件终结者:PullToRefreshLayout,后来看到好多人还有上拉加载更多的需求,于是就在前面下拉刷新控件的基础上进行了改进,加了上拉加载的功能。不仅如此,我已经把它改成了对所有View都通用!可以随心所欲使用这两个功能~~ 我做了一个大集合的demo,实现了ListView、GridView、ExpandableListView、ScrollView、WebView、ImageView、TextView的下拉刷新和上拉加载。后面会提供demo的下载

学无常师,负笈不远险阻 5万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android PullToRefresh下拉刷新,上拉加载的使用详解

哎,最近事真的是多。没有坚持写博客虽然写得差,但还是得坚持写嘛!不过,我发现虽然有很多想写得,但是发现大神们的博客上都写了。所有只能自己写点简单东西来

后知后觉者! 6919

打造Android万能下拉刷新上拉加载控件

转载请注明出处:http://blog.csdn.net/binbinqq86/article/details/70159782关于列表刷新加载的自定义控件,网上数不胜数,但别人的用起来始终不是那么得心应手,很早以前就想自己去实现一个属于自己的刷新控件,废话不多说,看图: 怎么样,感觉还不错吧~该控件支持AbsListview,Recyclerview,并且可以自己扩展其他类型的View,包括自动

Water的博客 7044

Android控件十三:SwipeRefreshLayout实现上拉加载和下拉刷新

SwipeRefreshLayout实现上拉加载和下拉刷新 原文:https://www.cnblogs.com/liunanjava/p/5860024.html 实例一:下拉刷新和上拉刷新都用SwipeRefreshLayout自带的进度条(默认上拉刷新没有效果) 代码实现: layout/activity_main.xml <?xml version="1.0" encoding=...

zk的博客 4730

安卓中Xlistview的上拉加载和下拉刷新

我们安卓中要实现listview的上拉加载和下拉刷新,使用的是一个名为Xlistview的控件,已经有些好的包 我们直接导入自己的工程就好这个是主mainactivity里面的代码,主要是初始化xlistview的控件,给xlistview控件设置监听,实现其接口中的两个方法,加载和刷新方法,一般就是我们所写的在网络请求数据的方法package com.example.xlistviewtest;i

black_xiaoji的博客 1008

Y-bao/PullRefreshView 2.0 通用弹性阻尼 和 下拉刷新、上拉加载控件

PullRefreshView简介:方便快捷的帮滑动控件添加弹性阻尼 和 下拉刷新、上拉加载的功能,支持所有纵向滑动控件(横向的工作中没遇到相应需求 所以没做),阻尼效果和下拉刷新、上拉加载的效果 都 支持重定义,拓展性强。项目地址Y-bao/PullRefreshView2.0目前开发到2.0,与之前版本的区别:1.之前的版本 比较倾向于 低版本的android系统,为了使在没有硬件加速和控件树刷

oYuanWa的专栏 1947

Android-PullToRefresh下拉刷新,上拉加载的使用详解

在Android开发中下拉刷新,上拉加载这个功能是一般商业应用的App中必不可少的一个功能效果。但是对于新手来说,自定义下拉刷新的ListView可能还是会遇到很多的问题。而对于要快速开发的公司来说,可能时间又比较紧张。那么这时候我们就要用到一个开源控件Android-PullToRefresh了。这个开源控件是一款非常优秀的开源控件,可以直接从Github上下载下来直接使用。下载链接地址:htt

liubcsdn的博客 4643

下拉刷新、上拉加载控件的写法(详解)

下拉刷新、上拉加载控件的写法(详解)本文详细讲解了下拉刷新、上拉加载控件的写法,如有需要完整代码可以到我的资源下载 先说一下心得: 这是一个自定义控件,自定义控件分为两种: 一种是完全认为定义的,比如说常见的开关按钮,这个是原生 控件没有的;另一种是在原生的控件上添加一些新的功能,比如说上拉加载下拉刷新控件就是继承了ListView而增加了一些新功能 构造函数——一个参数的构造函数用于java

Android_Study_OK的博客 2517

Android中RecyclerView实现下拉刷新上拉加载更多

在ListView中实现下拉刷新上拉加载更多是很方便的,在RecyclerView中要实现这个功能,需要一些新的思路,当然习惯后也是很简便的。下面开始这个过程的总结思路在RecyclerView中,默认没有HeaderView和FooterView,所以只能开发者自己来实现这两个View,通常的做法是:使用官方的刷新控件SwipeRefreshLayout来实现下拉刷新,然后自定义一个FooterV

classTC的博客 2105
上一篇: 用Canvas和属性动画造一只萌蠢的“小鬼”
下一篇: 一点点有助于巧用RecyclerView的小技巧
LaterEqualsNever
博客等级 码龄12年 297粉丝 61原创
评论 18
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值