Android-PullToRefresh 使用心得

2023-11-01 20:38

本文主要是介绍Android-PullToRefresh 使用心得,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


目前下拉刷新已经满大街都是,在自己的应用如果不使用这个模式的话,出门都不好意思和人家打招呼,该文章就是简单探讨下针对于 github 上的这个开源项目的使用心得。

为什么是它?因为在 stackoverflow 上大家都说它不错,所以就试试看吧!该项目的位置 Android-PullToRefresh 遗憾的是目前已经停止维护,但是已经足够强大所以不维护就不维护吧!

注意:对应的还有一个项目,也是这个作者刚刚开的 ActionBar-PullToRefresh 这个是在 actionbar 上增加下拉的效果,Android-PullToRefresh 这个工程在我们下拉的时候会有一个 view 显示出来,而这个工程直接就是利用 actionbar 来显示,注意这两者的区别

首先,看看目前几个主流 app 的下拉刷新的效果。

sina 微博



网易新闻


腾讯微博


接下来,是我们自己实现后的效果



从图片来看非常的相似,所以接下来我们就看看这个开源的 lib 如何使用。

源码下载下来之后将 library 这个目录中的代码放到一个位置,然后在主工程中去引用它,通常都是在主工程的 project.properties 中去指定引用的位置

[plain]  view plain copy
  1. android.library.reference.4=library/Android-PullToRefresh  

因为这个是我工程中加入的第四个引用的库,所以是 reference.4,如果这是你的第一个的话,那么应该是 reference.1,这个关于库的引用在 android sdk 的 samples 目录下可以找到了两个工程 " TicTacToeLib " 和 " TicTacToeMain " 来自己参考下。

好了,先 build 下Android-PullToRefresh 生成 jar 包,然后在 build 主工程,应该没什么问题,继续。

接下来就关于这个部分的使用,使用主要考虑两个方法:1. 这个 lib 的基本功能的使用,2. 这个 lib 的自定义扩展

基本功能的使用

1. 在 layout 文件中对应的 listview 不能使用 android 原生的 listview,而是要使用 PullToRefreshListView 代码如下

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.   
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     android:orientation="vertical">  
  7.   
  8.     <com.handmark.pulltorefresh.library.PullToRefreshListView  
  9.         xmlns:ptr="http://schemas.android.com/apk/res-auto"  
  10.         android:id="@+id/my_list"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="fill_parent"  
  13.         android:cacheColorHint="#00000000"  
  14.         android:fadingEdge="none"  
  15.         android:fastScrollEnabled="false"  
  16.         android:footerDividersEnabled="false"  
  17.         android:headerDividersEnabled="false"  
  18.         android:smoothScrollbar="true"  
  19.         ptr:ptrAnimationStyle="flip"  
  20.         ptr:ptrHeaderTextAppearance="@android:attr/textAppearanceMedium"/>  
  21.   
  22.     <!-- Here is the view to show if the list is emtpy -->  
  23.     <ScrollView android:id="@+id/empty"  
  24.         android:layout_width="fill_parent"  
  25.         android:layout_height="fill_parent"  
  26.         android:fillViewport="true">  
  27.   
  28.         <LinearLayout  
  29.             android:layout_width="fill_parent"  
  30.             android:layout_height="wrap_content"  
  31.             android:orientation="vertical">  
  32.   
  33.             <TextView  
  34.                 android:id="@+id/emptyText"  
  35.                 android:layout_width="fill_parent"  
  36.                 android:layout_height="fill_parent"  
  37.                 android:text="@string/noText"  
  38.                 android:textSize="20sp"  
  39.                 android:textColor="?android:attr/textColorSecondary"  
  40.                 android:paddingLeft="10dip"  
  41.                 android:paddingRight="10dip"  
  42.                 android:paddingTop="10dip"  
  43.                 android:lineSpacingMultiplier="0.92"  
  44.                 android:gravity="center" />  
  45.         </LinearLayout>  
  46.     </ScrollView>  
  47. </LinearLayout>  
在这个 layout 中分为上下两个部分,上面是一个 listview, 下面是一个 empty view,用来在没有内容的时候显示,通过 listview 的  setEmptyView() 就可以达到这个效果,千万不要自己费事去写两个 view 的逻辑控制代码。

关于 ptr:XXX 属性的使用,会在自定义扩展的那个部分解释下,这里暂时跳过。

2. 在代码中使用这个 listview,代码如下

[java]  view plain copy
  1. private PullToRefreshListView mList;  
  2.   
  3. @Override  
  4. protected void onCreate(Bundle savedInstanceState) {  
  5.     // ...  
  6.   
  7.     mList = (PullToRefreshListView)findViewById(R.id.my_list);  
  8.     mList.setEmptyView(findViewById(R.id.empty));  
  9.     mList.setOnItemClickListener(new OnItemClickListener() {  
  10.   
  11.         @Override  
  12.         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
  13.             if (DEBUG) Log.d(TAG, "onItemClick() : pos=" + position + ", id=" + id);  
  14.             parent.getAdapter().getItem(position);  // @warning: Should not use mAdapter  
  15.               
  16.             // do something  
  17.         }  
  18.   
  19.     });  
  20.   
  21.     mList.setOnPullEventListener(new OnPullEventListener<ListView>() {  
  22.   
  23.         @Override  
  24.         public void onPullEvent(PullToRefreshBase<ListView> refreshView, State state,  
  25.                 Mode direction) {  
  26.             if (DEBUG) Log.d(TAG, "onPullEvent() : " + state.name());  
  27.   
  28.             if (state.equals(State.PULL_TO_REFRESH)) {  
  29.                 refreshView.getLoadingLayoutProxy().setPullLabel(getString(R.string.pull_to_refresh));  
  30.                 refreshView.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.release_to_refresh));  
  31.                 refreshView.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.loading));  
  32.   
  33.                 String label = DateUtils.formatDateTime(getApplicationContext(),  
  34.                         System.currentTimeMillis(),  
  35.                         DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);  
  36.                 // Update the LastUpdatedLabel  
  37.                 refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(  
  38.                         getString(R.string.updated) + " : " + label);  
  39.             }  
  40.         }  
  41.     });  
  42.   
  43.     mList.setOnRefreshListener(new OnRefreshListener<ListView>() {  
  44.         @Override  
  45.         public void onRefresh(PullToRefreshBase<ListView> refreshView) {  
  46.             if (DEBUG) Log.d(TAG, "onRefresh()");  
  47.   
  48.             // Do work to refresh the list here.  
  49.             refresh();  
  50.         }  
  51.     });  
  52.   
  53.     // ...  
  54. }  
此处有几个地方要注意:
1. 如果想对 list item 点击之后做一些事情,此处有个问题要注意下,那就是我们的下来显示的 view 是 header view,所以此处在 onItemClick() 函数中传入的 position 不是从 0 开始而是从 1 开始,如果我们使用通常情况下的 mAdapter 去 getItem() 则实际中始终获取的都是我们点击 item 的下一个 item 的位置,所以此处我们要通过传进来的 parent 的 adapter 来获取 item,详细可以参考 当ListView有Header时,onItemClick里的position不正确

2. 因为下拉的时候显示的文字,每个人有每个的需求,所以会不一样,所以就需要使用 setOnPullEventListener() 来更新文字,这个开源库自己提供的 sample 中更新文字是放到 setOnRefreshListener() 中,但是那个只是在刷新的时候才更新问题,通过对比那些常用 app 的下拉效果你会发现那个时候在更新已经慢了,所以要放到这里

3. 此处代码没有列出来,就是 refresh 完了之后要把 pull view hide 起来,调用 onRefreshComplete() 即可,详情可以参考它自己提供的 sample。

4. 还要注意的是,还有很大的需求是点击刷新,那么点击之后这个 pull view 也要 show 出来,但是不应该 show "下拉可以刷新" 和 "松开可以刷新" 这两个画面,而是直接显示正在刷新的那个画面,这要怎么做到的呢?通过setRefreshing()这个函数即可做到,对应有另外一个函数叫做demo() 它包括了 “下拉->松开->刷新” 的整个过程,这是我们在这种条件下不需要的。

5. 在它自己的 sample 中还可以增加声音的效果,这个比较简单,自己看下即可。

Android-PullToRefresh 自定义扩展

此处的扩展指的是不修改这个开源库任何一行本身的代码来实现自定义一些属性,那些属性可以自定义这个可以在这个库的 values/attrs.xml 中看到,我们使用的时候就像上面 layout 中的写法一样,首先包含下命名空间,然后就可以指定对应的属性

[html]  view plain copy
  1. <com.handmark.pulltorefresh.library.PullToRefreshListView  
  2.         xmlns:ptr="http://schemas.android.com/apk/res-auto"  
  3.         android:id="@+id/my_list"  
  4.         android:layout_width="fill_parent"  
  5.         android:layout_height="fill_parent"  
  6.         android:cacheColorHint="#00000000"  
  7.         android:fadingEdge="none"  
  8.         android:fastScrollEnabled="false"  
  9.         android:footerDividersEnabled="false"  
  10.         android:headerDividersEnabled="false"  
  11.         android:smoothScrollbar="true"  
  12.         ptr:ptrAnimationStyle="flip"  
  13.         ptr:ptrHeaderTextAppearance="@android:attr/textAppearanceMedium"/>  
"xmlns:ptr="http://schemas.android.com/apk/res-auto" 声明下,然后可以使用 ptr:XXX 的属性了。

一些属性的简单说明

ptrAnimationStyle :  flip 这个效果是有向下和向上的两个箭头的,rotate 没有箭头不管怎么拉都是一个 progress bar

ptrMode :both 指的是 listview 的上面和下面都有这种拉动刷新的效果,下面的刷新通常我们在滑到最下面然后 loading 数据的时候可以看到

其他的属性可以在 attrs.xml 中看它的注释来理解,总之一句话,尽量少自己造轮子先看看作者有没有提供接口。



转自:http://blog.csdn.net/wwhh393/article/details/9722199

这篇关于Android-PullToRefresh 使用心得的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/325594

相关文章

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

使用Python的requests库调用API接口的详细步骤

《使用Python的requests库调用API接口的详细步骤》使用Python的requests库调用API接口是开发中最常用的方式之一,它简化了HTTP请求的处理流程,以下是详细步骤和实战示例,涵... 目录一、准备工作:安装 requests 库二、基本调用流程(以 RESTful API 为例)1.

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3