如何制作带有下拉刷新和下拉加载更多的列表

一般的APP软件都是需要下拉刷新,下拉加载这两个功能的,今天我们就来学习怎么样实现这两个功能。

我们先来讲一下他们的原理,这里我们将采取的方案是使用组合View的方式,先自定义一个布局继承自LinearLayout,然后在这个布局中加入下拉头和ListView这两个子元素,并让这两个子元素纵向排列。初始化的时候,让下拉头向上偏移出屏幕,这样我们看到的就只有ListView了。然后对ListView的touch事件进行监听,如果当前ListView已经滚动到顶部并且手指还在向下拉的话,那就将下拉头显示出来,松手后进行刷新操作,并将下拉头隐藏。下拉加载更多也是同样的原理。

首先我们需要一个页面布局来存放我们需要实现页面。我们新建一个PullToRefresh.axml的页面:

PullToRefresh.axml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="25px"
    android:minHeight="25px"
    android:background="#ffffffff">
    <PullToRefresharp.Android.Views.ViewWrapper
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <PullToRefresharp.Android.Widget.ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/listview1"
            android:divider="#ff999999"
            android:dividerHeight="1px" />
    </PullToRefresharp.Android.Views.ViewWrapper>
</FrameLayout>

这是用来存放下拉刷新控件的页面上。

我们还需要一个获取更多的页面。我们新建一个叫listloadmorefooter.axml的页面。

页面布局代码如下:

listloadmorefooter.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal"
    android:orientation="horizontal"
    android:padding="15dp"
    android:background="#ffffffff">
    <ProgressBar
        android:id="@+id/pb_load_progress"
        style="@android:style/Widget.ProgressBar.Small.Inverse"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:indeterminate="true" />
    <TextView
        android:id="@+id/tv_load_more"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10.0dp"
        android:gravity="center"
        android:text="加载中" />
</LinearLayout>

这样两个布局的页面就弄好了,我们可以在活动中写下拉刷新的代码了。

接下来我们来看一下具体的功能页面的实现代码。

public class PullDownRequest
    {
        //定义传送类型
        public PtrRequest PtrRequest;
        public RequestType request;
    }
   public class PullDownResult
   {
       //定义接收类型
       public ResultType Type;
       //失败内容
       public string ErrorMsg;
   }
    //自定义枚举类型
   public enum RequestType
   {
       /// <summary>
       /// 我的活动
       /// </summary>
       Mine = 0,
       /// <summary>
       /// 发布的活动
       /// </summary>
       Manager = 1,
       /// <summary>
       /// 已结束的活动
       /// </summary>
       Finish = 2,
       /// <summary>
       /// 缺席的活动
       /// </summary>
       Leave = 3,
       /// <summary>
       /// 招募活动
       /// </summary>
       All = 4
   }
   public enum ResultType
   {
       /// <summary>
       /// 成功
       /// </summary>
       Success = 0,
       /// <summary>
       /// 失败
       /// </summary>
       Error = 1

   }

首先我们自定义枚举类型,因为我们这里有多个页面需要下拉刷新,所以就需要判断是哪个页面操作了下拉刷新,在我们调用下拉刷新方法时需要将它作为参数传进去。当然,有传送就必定会有接收,我们也需要知道反馈的结果是正确还是错误的,这就需要再自定义接收类型,假如是错误的,我们还需要知道错误的内容,所以这里就又加了个ErrorMsg。

之前我说过,下拉刷新会更新我们的本身的数据库,有可能添加、修改或删除。所以在这里我们还需要设计一个数据库。设计数据库对各位来说都比较简单,在这里就不再阐述了,所以下面就直接贴出。

public class ActivityDB
    {
        public int IndexId { get; set; }
        public string ActivityName { get; set; }
        public string TeamName { get; set; }
        public string UserName { get; set; }
        public DateTime ActivityStartTime { get; set; }
        public DateTime ActivityEndTime { get; set; }
        public string ActivityLocation { get; set; }
        public string ActivitySummary { get; set; }
        public string ActivityState { get; set; }
        public int ActivityAttend { get; set; }
        public int JoinCount { get; set; }
        public long Tick { get; set; }
        public bool IsJoining { get; set; }
        public int Id { get; set; }
}

除此之外,我们还应该新建消息。因为我们需要接收WEB给我们传送的提示,以便让我们知道数据到底有没有更新。下面的代码就是新建消息。

 /// <summary>
        /// 刷新数据
        /// </summary>
        public const int RefreshData = 0x0538;
        /// <summary>
        /// 获取更多
        /// </summary>
        public const int LoadMoreData = 0x0539;
        /// <summary>
        /// 无数据
        /// </summary>
    public const int NoData = 0x0540;

其实上面我们一直都在做着准备的工作,接下来才是真正下拉刷新的核心,而我在一开始就把下拉刷新的流程给大家做了介绍,所以下面的代码看起来应该没有太大的问题。

public void GetAllActivities(int skip, int count, int messageCode,RequestType stype, Handler handler)
        {
            //新建一个线程
            Task.Factory.StartNew(() =>
            {
                try
                {
                    //判断网络连接
                    if (NetworkState.IsConnectivityMobile || NetworkState.IsConnectivityWifi)
                    {
                        //将当前页数、条数、GUID、当前本地数据库一起打包
                        PullDownRequest request = new PullDownRequest
                        {
                            request = stype,
                            PtrRequest = new PtrRequest
                            {
                                Skip = skip,//当前第几页
                                Count = count,//当前第几条
                                Guid = Guid.NewGuid().ToString(),//创建一个GUID,目的是使其唯一
                                LocalData = new List<PtrUpdateParam>()//将本地数据库传递给WEB端进行比较
                            }
                        };

                        PtrResponse<ActivityDB> response = null;
                        //打包后利用与WEB端交互的方法传递
                        response = _reposity.GetActivitiesData(request);
                        //判断数据到底有没有更新
                        //如果有更新,就执行下面的代码
                        if (response.UpdateData.Count() >= 0)
                        {
                            //新建一个消息
                            //新建一个Bundle类型的变量,将从WEB端传来的数据转换成JSON格式赋给它
                            //再将这个Bundle类型的变量赋给消息
                            //消息利用handler传递
                            Message msg = new Message();
                            msg.What = messageCode;
                            Bundle bundle = new Bundle();
                            String value = JsonConvert.SerializeObject(response.UpdateData.Select(x => x.Data).ToList(), new JavaScriptDateTimeConverter());
                            bundle.PutString(MessageCode.DataKey, value);
                            msg.Data = bundle;
                            handler.SendMessage(msg);
                            if (response.UpdateData.Count < 10)
                            {
                                handler.SendEmptyMessage(MessageCode.NoData);
                            }
                        }
                            //如果数据没有更新,就直接传递一个无数据的消息
                        else
                        {
                            handler.SendEmptyMessage(MessageCode.NoData);
                        }
                    }
                        //如果当前并没有网络,那么也是直接传递一个无数据的消息
                    else
                    {
                        handler.SendEmptyMessage(MessageCode.NoData);
                    }
                }
                    //捕捉与WEB端交互发生的错误
                catch (WebException ex)
                {
                    ExceptionManager.HandlerWebException(ex, handler);
                }
                //捕捉转换JSON格式时发生的错误
                catch (JsonException)
                {
                    handler.SendEmptyMessage(MessageCode.ConvertError);
                }
                    //发送一个初始化状态的消息
                finally
                {
                    handler.SendEmptyMessage(MessageCode.ResetState);
                }
            });
        }

上面就是我一开始所说的下拉刷新的核心,但是这还不算完,当WEB端那里传来消息后,我们肯定需要对此进行操作,更新数据或者获取更多。所以,这就要用到下面的代码。

//根据传来的消息决定到底要执行哪种方法
            switch (msg.What)
            {
                    //获取更多的方法
                case MessageCode.LoadMoreData:
                    {
                        //新建一个value,并将传来的key值赋给它
                        //实例化一个数据库变量,通过value将之前转换成json格式的数据反序列化并赋给数据库变量
                        //将数据库变量放入本地数据库中,总量产生变化
                        //通知数据发生变化
                        //改变获取更多的属性
                        String value = msg.Data.GetString(MessageCode.DataKey);
                        IList<ActivityDB> more = JsonConvert.DeserializeObject<IList<ActivityDB>>(value, new JavaScriptDateTimeConverter());
                        ListData = ListData.Concat(more).ToList();
                        TotalCount += more.Count;
                        NotifyDataSetChanged();
                        IsLoadMore = false;
                    }
                    break;
                    //刷新数据的方法
                case MessageCode.RefreshData:
                    {
                        //清空当前数据库
                        //实例化一个数据库变量,通过value将之前转换成json格式的数据反序列化并赋给数据库变量
                        //将数据库变量放入本地数据库中,总量产生变化
                        //显示“正在加载”
                        //通知数据发生变化
                        //改变获取更多的属性
                        ListData.Clear();
                        String value = msg.Data.GetString(MessageCode.DataKey);
                        IList<ActivityDB> more = JsonConvert.DeserializeObject<IList<ActivityDB>>(value, new JavaScriptDateTimeConverter());
                        ListData = more;
                        TotalCount = more.Count;
                        ListView.OnRefreshCompleted();
                        LoadMoreTv.Text = "正在加载";
                        NotifyDataSetChanged();
                        IsLoadMore = false;
                    }
                    break;
                    //无数据
                case MessageCode.NoData:
                    {
                        //显示“已加载完毕”
                        //将显示更多的加载条设置为隐藏
                        LoadMoreTv.Text = "已加载完毕";
                        LoadMoreBar.Visibility = ViewStates.Gone;
                    }
                    break;

大部分的解释都写在代码中了,大家如果不明白的可以仔细的去看一下。

如果对我写的内容不明白的话,可以去看一下http://www.cnblogs.com/yaozhenfa/p/xamarin_android_pulltorefresharp.html 这篇文章。

时间: 2024-10-09 13:09:18

如何制作带有下拉刷新和下拉加载更多的列表的相关文章

Android如何定制一个下拉刷新,上滑加载更多的容器

前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉刷新和上滑,非常考验对android布局与父子触摸机制的功底,因此参考gitHub上的一个热门的下拉刷新项目 之所以选择他是因为它一个类就完成了所有View的适配,非常的精简强力. 需求 咱对下拉刷新.上滑加载更多的控件,需求如下: 1:下拉刷新,拖动到一定距离,提示文字变成 放手刷新 2:刷新完成

android ListView的上部下拉刷新下部点击加载更多具体实现及拓展

转自:http://blog.csdn.net/jj120522/article/details/8229423 这次就不上图了,例子太多太多了,想必大家都见过.这个功能的实现,简直是开发者必备的. 我也不过多介绍了,网上详细介绍的博客太多太多了,若想深入了解,请参考网上其他博文. 在这里,我只是按照自己的理解,模拟实现了一个,顺便代码贡献出来. 我对之详细标明的注释,想必如果不懂的同学们,看注释也应该明白,前提是,你要耐心看,因为代码有点多,但是我整理过了,还算清晰. 详细代码: [java]

Android 下拉刷新,上滑加载更多

底部上拉效果 public class ListViewFooter extends LinearLayout { public final static int STATE_NORMAL = 0; public final static int STATE_READY = 1; public final static int STATE_LOADING = 2; private Context mContext; private View mContentView; private View

Android 为什么我的PullListView只能向下滑动,不能向上滑动加载更多???

============问题描述============ Android 为什么我的PullListView只能向下滑动,不能向上滑动加载更多??? ============解决方案1============ mode模式,你可以看看官方api

Android 自定义 ListView 上下拉动&ldquo;刷新最新&rdquo;和&ldquo;加载更多&rdquo;歌曲列表

本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码太多,点击此处下载,自己调试一下. 下载 Demo 环境 Windows 2008 R2 64 位 Eclipse ADT V22.6.2,Android 4.4.3 SAMSUNG GT-I9008L,Android OS 2.2.2 测试数据 本演示的歌曲信息,共有 20 条,包括歌手名.歌曲名.时长.缩

Ionic -- Refresher &amp; InfiniteScroll 下拉刷新与滚动懒加载

下拉刷新和滚动加载在移动端是很常见的需求,Ionic 为我们提供了开箱即用的组件.在这里我结合自己做的小demo简单介绍下. Template 在模板中需要将 ion-refresher 组件放置在 ion-content 内部的首位,将 ion-infinite-scroll 置于尾部. <ion-refresher (ionRefresh)="doRefresh($event)"> <ion-refresher-content pullingIcon="

ListView实现下拉刷新-2-将顶部布局加载到ListView中

上一篇实现了Adapter类的创建,和getView函数的分析: 这一篇主要讲第二部分,即将顶部布局加载到ListView中:重点是ReFlashListView的实现上,这一篇中我会谈一谈在阅读源代码的过程中所遇到的困难和采取的方法: 首先看ReFlashListView类: public class ReFlashListView extends ListView implements OnScrollListener 表明ReFlashListView是继承自ListView的,并且 实现

iOS学习之路--下拉刷新和上拉加载更多

iOS学习之路--下拉刷新和上拉加载更多 简介 本文中笔者将和大家分享应用app中常用到的表单内容的下拉刷新和上拉加载更多的功能实现的方法. 内容 1.有哪些实现方法与各方法的优劣 使用过美团,大众点评的朋友们应该有注意到,当你向上滑动表单的时候会有更多的店铺加载进你的表单中,而当你下滑表单顶的时候,则会刷新表单的内容并从网络上获取最新的信息.通过下拉刷新和上拉加载更多的功能,使app可以获取更多用户想要的信息和获取最新的信息.那么这种功能如何实现呢,还请跟着笔者继续往下看. 目前来说,主要的实

【好程序员笔记分享】——下拉刷新和上拉加载更多

-iOS培训,iOS学习-------型技术博客.期待与您交流!------------ iOS学习之路--下拉刷新和上拉加载更多 简介 本文中笔者将和大家分享应用app中常用到的表单内容的下拉刷新和上拉加载更多的功能实现的方法. 内容 1.有哪些实现方法与各方法的优劣 使用过美团,大众点评的朋友们应该有注意到,当你向上滑动表单的时候会有更多的店铺加载进你的表单中,而当你下滑表单顶的时候,则会刷新表单的内容 并从网络上获取最新的信息.通过下拉刷新和上拉加载更多的功能,使app可以获取更多用户想要