当前位置: 首页 > article >正文

一起撸个朋友圈吧(step1) ListView(完结)篇

项目地址:github.com/razerdp/Fri…

上篇链接:http://www.jianshu.com/p/94e1e267b3b3

下篇链接:http://www.jianshu.com/p/94403e45fbef

在上一篇里面,最后我留下了一个问题,就是关于耦合度的问题。 经过思考后,个人认为,原框架留下了PtrHandler和PtrUIHandler为的就是解耦,我们要实现一个别的下拉header,只需要实现这两个接口就可以联调控制了,也就是ptrframelayout和这两个接口必定是相互依赖的,而不能说我们脱离框架来进行扩展。

同样,我们外部添加的刷新icon其实是可有可无,内部做好空引用判断防止崩溃,这个刷新icon是可有可无的,而且icon由下拉header控制的好处是外部不需要执行什么回调来控制(毕竟回调地狱你懂的),对外部来说,我需要做的,只是在布局文件中放好imageview,然后set进去就完了,其他不管。


今天这篇文章将会是ListView定制的最后一篇。今天要实现的是昨天留下的手尾:上拉加载更多。

不多说,先上图:

事实上,个人觉得加载更多是实现最简单的。。。特别是对listview来说。

因为listview自带footerView,有了这个footerview,我们就可以定义我们的加载更多布局来实现各种各样的加载更多了。

吹逼吹完了,我们就开工吧(←_←)

首先,依然是布局文件入手,我们的布局文件也是十分简单,只有两个view

其中因为某些原因,我们的加载那朵菊花需要特别定制一下。为何? 如果细心观察,可以看到那朵小菊花其实是在转动的时候有明暗变化的,ios因为自带有,所以不用管,可android的原生progressbar是个圆环啊,要变成菊花,只好兼职一回设计师,拉出我们的AE(在下不会PS)

用形状图层画一个明暗变化的棍子,在旋转属性上打上index30和透明度属性上打上100-(index5),然后不断地复制图层就有了一朵菊花了。

播放起来是这样的,转起来是不是有模有样←_←(看久了会晕的)


扯回来我们的as,布局弄好后就是写java了

构造器什么的我们就不管了,我们的footer依然使用PtrUIHandler,虽然这个回调不需要在ptrframelayout注册,但为了方便我们还是用它吧。

  //=============================================================ptr:private PtrUIHandler mPtrUIHandler = new PtrUIHandler() {/**回到初始位置*/@Overridepublic void onUIReset(PtrFrameLayout frame) {if (mRotateIcon==null)return;mRotateIcon.setVisibility(GONE);mRotateIcon.clearAnimation();loadingText.setText(LOAD_MORE);}/**离开初始位置*/@Overridepublic void onUIRefreshPrepare(PtrFrameLayout frame) {}/**开始刷新动画*/@Overridepublic void onUIRefreshBegin(PtrFrameLayout frame) {loadingText.setText(LOADING);if (mRotateIcon.getAnimation() != null) {mRotateIcon.setVisibility(VISIBLE);mRotateIcon.clearAnimation();}mRotateIcon.startAnimation(rotateAnimation);}/**刷新完成*/@Overridepublic void onUIRefreshComplete(PtrFrameLayout frame) {mRotateIcon.setVisibility(GONE);mRotateIcon.clearAnimation();loadingText.setText(LOAD_MORE);}/**位移更新重载*/@Overridepublic void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {}};
复制代码

这回相比于header,我们只需要定义几个地方:

  • 初始状态:菊花隐藏,文字定义为“加载更多”
  • 刷新状态:菊花显示,同时播放动画,文字定义为“正在加载”
  • 完成状态:菊花隐藏,文字定义为“加载更多”

大概就是这三个地方。

然后就是针对是否还有更多数据加载,我们用的是一个布尔值,这个值应该是由服务器下发的,因为只有服务器才知道有没有更多的数据。 所以我们预留一个接口:

    public void setHasMore(boolean loadMore){if (loadMore){mRotateIcon.clearAnimation();}else {mRotateIcon.clearAnimation();mRotateIcon.setVisibility(GONE);loadingText.setText(LOAD_ALL);}}
复制代码

当loadmore有的时候,意味着还有更多数据加载,我们就清掉菊花的动画,如果没有,我们就隐藏菊花,文字定义为“已经全部加载”提示用户后面没有数据了。

footer大概就是这么多内容,接下来就是回到我们的listview进行联调了

在昨天,我们setScrollListener方法里面预留了位置,但未处理,哪个地方就是用来加载更多的,那么今天我们就把它完成了

回到我们的setScrollListener

   private void setScrollListener() {mListView.setOnScrollListener(new AbsListView.OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {if (mOnLoadMoreRefreshListener != null) {if (SCROLL_STATE_IDLE == scrollState &&0 != mListView.getFirstVisiblePosition() && lastItem == mListView.getCount()) {if (hasMore && loadmoreState != PullState.REFRESHING) {//当有更多同时当前加载更多布局不在刷新状态,则执行刷新curMode = PullMode.FROM_BOTTOM;changeLoadMoreState(PullState.REFRESHING);}}}}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {lastItem = firstVisibleItem + visibleItemCount;}});}
复制代码

在if条件里面我们把模式换位frombottom,同时调用changeLoadMoreState来更改footer的状态。

因为执行到这个if里面,此刻的状态必定是有更多数据加载,用户滑到了底部,同时footer处于非刷新状态,所以我们直接更改为刷新状态就可以了。

接下来看看changeLoadMoreState方法

    private void changeLoadMoreState(PullState curLoadMoreState) {final PtrUIHandler footerHandler = mFooter.getPtrUIHandler();switch (curLoadMoreState) {case NORMAL:footerHandler.onUIReset(this);break;case REFRESHING:footerHandler.onUIRefreshBegin(this);if (mOnLoadMoreRefreshListener != null) mOnLoadMoreRefreshListener.onRefreshing(this);break;default:break;}loadmoreState = curLoadMoreState;}
复制代码

这个方法里面我们只需要根据状态调用footer的ptruihandler就好了,同时在刷新的时候把刷新接口回调出去,其他不用管。

这时候也许有疑问了,我们的footer没有看到相关的addview操作啊。 其实文章写到这里的时候我也发现了- - 我也忘记footer还没弄到listview里面了。 思考一番后,我打算将footer在setHasMore方法里面添加

   public void setHasMore(boolean hasMore) {if (mOnLoadMoreRefreshListener == null) return;if (mListView.getFooterViewsCount() == 0 && hasMore) {mListView.addFooterView(mFooter);}mFooter.setHasMore(hasMore);this.hasMore = hasMore;}
复制代码

也就是如果有更多数据的时候,添加我们的footer 至此,我们的加载更多就完成了,最后还要做的,就是将加载完成的方法暴露,毕竟框架只有下拉刷新的完成回调而没有加载更多的回调啊。

    public void loadmoreCompelete() {changeLoadMoreState(PullState.NORMAL);}
复制代码

这样,我们在activity就可以这么使用了:

        mFriendCirclePtrListView.setOnPullDownRefreshListener(new OnPullDownRefreshListener() {@Overridepublic void onRefreshing(PtrFrameLayout frame) {frame.postDelayed(new Runnable() {@Overridepublic void run() {mFriendCirclePtrListView.refreshComplete();}},1800);}});mFriendCirclePtrListView.setOnLoadMoreRefreshListener(new OnLoadMoreRefreshListener() {@Overridepublic void onRefreshing(PtrFrameLayout frame) {new Thread(new Runnable() {@Overridepublic void run() {SystemClock.sleep(1500);for (int i=0,size=test.size();i<20;i++){test.add("test"+(size+i));}}}).start();frame.postDelayed(new Runnable() {@Overridepublic void run() {mFriendCirclePtrListView.refreshComplete();adapter.notifyDataSetChanged();mFriendCirclePtrListView.setHasMore(false);}},3000);}});}
复制代码

当然,我们以后会进行一下封装 ps:因为在下没有服务器,所以只能靠本地模拟网络延迟和数据更新了,所以只能手动设置setHasMore,这些操作其实应该是靠请求完成的。

OK,我们撸个朋友圈的计划已经踏出了一步了,起码把listview框架搭建好,那么下一篇,我们将担任一下后端,来设计一下我们的数据结构吧(JSON结构)

http://www.lryc.cn/news/2415651.html

相关文章:

  • 强烈推荐没事都看看.
  • 解决element-ui.common.js?5c96:3:Navigation cancelled from “/admin“ to “/users“ with a new navigation.
  • Ubuntu设置CPU频率cpufrequtils
  • Windows 7“God Mode”(上帝模式)
  • 全球50大变态网站
  • 使用Arduino,蓝牙和Android app的开源爬墙机器人
  • 人事管理系统平台(源码+开题)
  • 升级cisco设备的IOS
  • VC6.0(Visual C++ 6.0) 建立一个简单的C语言工程
  • DD373自动发布工具/DD373辅助/DD373外挂
  • toolkit 和 toolbox的区别 what the difference between ‘toolkit‘ and ‘toolbox‘
  • 2024七款最佳的渗透测试工具_网络安全渗透工具
  • win7下桌面IE快捷方式无法删除解决方法
  • dede模板里常用到的一些标签—dedecms模板开发
  • Web安全 Acunetix漏洞扫描工具.
  • DIV CSS绝对定位布局案例 position布局实例
  • puppet安装与使用--模块结构(iptables与rsync模块)
  • 【Linux笔记】压缩、解压文件的 4 种方式。tar、gzip、gunzip、zip、unzip、7z命令使用方法
  • 代理网站
  • 浅谈www.baidu.com和baidu.com
  • 基于VHDL语言的数字电子钟设计
  • 上网的数据包交互过程
  • vs2005 调试技巧
  • 华为云CloudIDE的抄袭真相?
  • B站后台源码疑似泄露,作为程序员我们得注意哪些?
  • 基础算法——二分(C语言版)
  • 辽宁网络营销网站建设的步骤-网站设计营销内容
  • Django 基于类的通用视图详解
  • Objective-C 基础语法详解
  • WebService之XFire和SOAP实例(基于JAVA)