这个版本号的博客写起来颇费口舌。有些代码自己语言组织能力有限,感觉描写叙述起来非常费劲,前前后后改了五六遍稿子还是不尽人意 ,只是我还是坚持写出来自己当初的思路,假设看得不明确的地方我在文章最后仍然会上传源码,能够直接执行看效果,看过执行的效果后对文中有些别扭的语言预计会能直观的了解。在版本号3.0的尽管实现了随着手指的左右移动listView中的item也随着滚动。可是会出现例如以下的情况:

当左边已经是第一个的时候,会出现例如以下的情况(仍然能够向右移动):

当右边是adapter最后一个item的时候,会出现例如以下的情况(仍然能够向左移动):

正常来说,当左边第一个和右边最后一个应该不能滚动才是,本4.0版本号将解决问题。在解决问题之前先说说相关的知识点:

知识点1):手指在屏幕上移动的时候,会发生 其它相关方法...>onScroll-->onScroll-->onScroll ..-->其它相关方法.这种调用

知识点2):3.0版本号在处理手指滚动的时候用到了onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY)这种方法,这种方法中有个distanceX參数。这个參数我们知道,当手指想做移动的时候distanceX>0;而手指向右移动的时候distanceX<0;这是由于distanceX的值是由第二个參数决定的:distanceX = 上次掉用onScroll方法的e2.getX()-当前onScroll方法的e2.getX()或者简写成 lastEvent2.getX() - currentEvent2.getX() = distanceX;

在版本号3.0的时候我们直接用distanceX这个变量(确切的说这个变量值的相反数来模拟左右移动滚动的距离),可是这次为了解决上面的问题我们将不再直接用distanceX,而是新定义了两个变量:

变量:preTotalDistanceX :相对于当前onScroll方法调用之前。之前全部onScroll调用所产生的距离之和。比方当前是第n次调用了onScroll。那么preTotalDistanceX=前n-1次调用onScroll中distanceX的累加和;

变量:totalDistanceX:当前调用onScroll方法方法调用中全部distanceX的累加和;比方当前是第n次调用了onScroll方法,那么totalDistanceX就是n个onScrll方法调用中參数里distanceX的累加和。

那么滚动的距离distanceX = totalDistanceX - preTotalDistanceX

用代码表示总距离例如以下:

            public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {totalDistanceX += distanceX;requestLayout();return true;};

该版本号onLayout的方法就改动例如以下:

      int distanceX = totalDistanceX - preTotalDistanceX; removeAnvisiableViews(-distanceX);addRightChildViews(-distanceX);addLeftChildViews(-distanceX);layoutChildViews(-distanceX);preTotalDistanceX = totalDistanceX;

要解决文章开头提出的问题,关键是让distanceX = 0;即pretotalDistanceX=totalDistanceX;所以解决这个问题的关键就是怎样让这两个变量相等。从知识点2能够知道,如果用户的手指先右后左:此时最左边的item是adapter的第一个item,所以手指向右移动的时候不能让listView向右滚动,可是实际上随着手指的向右移动totalDistanceX变量是<0,并沿着平面直角坐标系远离0点而负递增,所以在这里能够初步推断:当totalDistanceX<=0的时候,让totalDistanceX = 0;这样preoTotalDistanceX=totalDistanceX=0,这样就会让distanceX=0,从而不会让我们的ListView不会向右移动;如果用户的手指先左后右的移动方式:当手指向左移动的时候totalDistanceX>0且不断增大。是递增的。而当手指右移动的时候totalDistanceX是在原来的基础上不断降低的过程,当较少到0的时候继续向右移动的话totalDistanceX变为负数,继续向右移动的话就类似与手指先右后左的现象了;这个是关键的地方。整个左右移动的过程发生诡异的变化类似于物理中的位移。当totalDistanceX=0的时候我们能够断定不能在向右滚动。

所以在onLayout代码中我做了例如以下推断:

@Overrideprotected void onLayout(boolean changed, int left, int top, int right,int bottom) {if (listAdapter == null) {return;}/**确保党左边是第一个的时候不再滚动*/if(totalDistanceX<=0) {totalDistanceX = 0;}int distanceX = totalDistanceX - preTotalDistanceX;removeAnvisiableViews(-distanceX);addRightChildViews(-distanceX);addLeftChildViews(-distanceX);layoutChildViews(-distanceX);preTotalDistanceX = totalDistanceX;}

执行一把发现上面的设想是成立的。到此为止,博客开头的第一个问题得到了解决。
以下将解决第二个问题:当adapter里面最后一个item加入到viewGroup里面而且全然显示的时候,禁止listView继续向左滚动。

先看最有一个item没有显示全然的情况,例如以下图:

解决第二个问题的关键仍然是怎样让distanceX= totalDistanceX-pretotalDistanceX=0。也就是怎样让totalDistanceX=preototalDistanceX;依据图示我们非常easy得出例如以下结论:要让最后一个item显示完。在之前滚动距离总和的基础上再让listView滚动X大小的距离能够了,用上面的等式表示为totalDistanceX=X+pretotalDistanceX,所以当totalDistanceX>X+pretotalDistanceX的时候我们让 totalDistanceX = X+preototalDistanceX;在程序用我是用scrollXMax来表示X+preototalDistanceX的值(此变量名起的有点垃圾);在代码用为:

//scrollXMax = X + pretotalDistanceX
if(totalDistanceX>scrollXMax) {totalDistanceX = scrollXMax;
}......
preototalDistanceX = totalDistanceX;

这样当最后一个item滚动了X距离的情况下调用layout绘制到listView之后,手指在移动的情况下if(totalDistanceX>scrollXMax仍然成立)。这样计算的distanceX=0.可是话有说回来了,X+preDistanceX这段代码加入到哪儿呢?结合之前的几篇博客,不难分析出应该在addRightChildViews方法里面加入,代码例如以下:

private void addRightChildViews(int distanceX) {// 2.让屏幕尽可能的显示Item。注意刚開始的时候是没有View rightChildView = getChildAt(getChildCount() - 1);// 获取此childView右边框距离parentView左边框的距离int rightEdge = rightChildView != null ?

rightChildView.getRight() : 0; while (rightEdge + distanceX < getWidth() && rightIndex < listAdapter.getCount()) { View child = listAdapter.getView(rightIndex, null, null); child = measureChild(child); addViewInLayout(child, -1, child.getLayoutParams(), true); rightEdge += child.getMeasuredWidth(); //推断最后一个item if (rightIndex == listAdapter.getCount() - 1) { scrollXMax = rightEdge +preTotalDistanceX- getWidth(); } rightIndex++; } }

到此位置。上面的的两个问题都得到圆满解决。自己在整这个版本号的时候走了不少弯路,捣鼓了半天,到最后完成还是有种小小的成就感;何为编程。说白了就是在遵循特性编程语言规则的情况下,用该编程语言描写叙述或者表达程序猿思路的过程。

在4.0版本号的实现中。自己在纸上又是写又是画的,思路清晰了然后就非常自然而然的用编程语言把这个思路表达出来。这就是编程吧!啰嗦完成。当然该版本号还没有完好完成,比方说不能点击就是这个,将在下一个版本号解决剩余的问题。时间同意的话直接写完。此处为项目源代码,欢迎批评指正

简单的横向ListView实现(version 4.0)相关推荐

  1. 简单的横向ListView实现(version 3.0)

    版本号2仅仅是简单的实现了当手指按下的时候listView的Item向左移动一定的距离,并没有随着手指的左右移动而左右滚动.在这个版本号3.0中将会实现随着手指的移动而滚动的目标:当手指向左移动的时候 ...

  2. Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现 (附源码下载)

    本文内容: 1.横向ListView的所有实现思路; 2.其中一个最通用的思路HorizontalListView,并基于横向ListView开发一个简单的相册: 3.实现的横向ListView在点击 ...

  3. Android横向ListView功能实现

    --在开发类似新闻功能的App过程中需要在新闻页面展示新闻附件,附件一多的话一行展示不完,换行又不好看,为此需要做像今日头条导航栏那样可以横向滑动的列表,不同点在于附件数量是动态添加的 可能有一个 也 ...

  4. 横向ListView(一) ——开篇,基础逻辑实现

    2019独角兽企业重金招聘Python工程师标准>>> 第一次写博文,写得不好的地方还望各位看客见谅 为了学习自定义软件开发,且定制出满足自己需求的控件(不需要将就地使用第三方源码) ...

  5. HorizontalListView 横向listview

    tag:HorizontalListView 横向listview  仿 优酷 播放列表 由于优酷的客户端很酷,最近在做视频列表的时候客户要求做出类似效果,开始打算用Gallery的,不过后来发现横向 ...

  6. Android 横向滚动列表 (类似横向ListView)

    示例: 布局代码***.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  7. 张高兴的 UWP 开发笔记:横向 ListView

    ListView 默认的排列方向是纵向 ( Orientation="Vertical" ) ,但如果我们需要横向显示的 ListView 怎么办? Blend for Visua ...

  8. java51_Java运行 Unsupported major.minor version 51.0 错误

    今天写了简单的Java程序,运行的时候不知道为啥出现这个问题 happy@happy-HP-Compaq-dx7518-MT:~/Study/CrazyJava$ java FieldTest Exc ...

  9. 横向ListView(四) —— 添加滚动条

    2019独角兽企业重金招聘Python工程师标准>>> 在前面的文章已经介绍了横向ListView的基础实现及头尾视图的添加等的实现,这篇文章将介绍为横向ListView添加滚动条: ...

最新文章

  1. 海量数据库解决方案2011031701
  2. 深入理解JVM虚拟机(五):字节码指令简介
  3. Qt,编译libcurl并且导入到库
  4. 微信小程序 rpx和px转换
  5. C语言:格式字符串中的类型
  6. SpringBoot的基础
  7. 你应该关注的几个网站
  8. 关于Word2016敲入公式的新方法
  9. html5图片列表纵向,div css图片列表实例布局案例ul li布局
  10. [转载] c++list遍历_List、Set、数据结构、Collections
  11. [2018.11.05 T2] 买牛奶
  12. MATLAB矩阵运算
  13. OpenGL学习(七)通过assimp库读取多种格式的模型
  14. 春节感悟 - 原年人的爱和恨
  15. java的cursor_JAVA中类 Cursor的定义.
  16. lvm硬盘扩容了,或者使用fdisk格式化大于2T硬盘后,如何通过pvresize扩容
  17. linux无法更改屏幕亮度调节软件,在Deepin系统中安装闭源显卡驱动后屏幕亮度无法调节的解决...
  18. python中随机生成数字方法
  19. 深度学习基础之-2.3简单的神经网络(单个输入/多个输入)做线性回归+特征值归一化
  20. 如何让你画里的鱼,游进海里?

热门文章

  1. java cache system_JCS(Java Cache System)基本结构分析和使用
  2. mybaitis快速生成_Mybatis中使用mybatis-generator结合Ant脚本快速自动生成Model、Mapper等文件...
  3. 简述linux开机启动进程,Linux系统启动流程简述
  4. swiper.js插件的使用
  5. java io读取文件_java io读取文件操作代码实例
  6. 2019-0404视觉SLAM的学习第三讲01
  7. 字符串解压缩c语言除哈夫曼,C语言实现压缩二例(示例代码)
  8. orcale建表,创建字段id使其自增
  9. 几种测量app启动时间的方式
  10. 转型个股赚钱机会最大--封起“345”选股