文档章节

开源中国 OsChina Android 客户端源码分析(3)可以拖拽的ScrollView

姬鑫
 姬鑫
发布于 2015/05/20 15:07
字数 943
阅读 805
收藏 13

      oschina客户端滑动菜单的View的布局使用了可以拖拽的ScrollView,类文件为CustomerScrollView。

      1 我们需要分析下为什么要用ScrollView?用过的其实很容易理解避免其内部的子View的布局较大,在较小设备上无法完全显示。

      2实现可拖拽的效果,只是从用户体验角度去考虑的,接下来我们详细分析下其自定义的ScrollView。

      2.1拖拽的目标是ScrollView内的菜单的布局View,所以在CustomerScrollView内的onFinishInflate()函数中首先通过getChildAt(0)来获取菜单布局的View,这就是第一步的目标是获取要拖拽的对象。onFinishInflate()加载完view,这里的View指的就是源码中<include layout="@layout/fragment_navigation_drawer_items"/>加载的布局文件。

     2.2拖拽的过程实际上是一个“按下-移动-抬起”的过程,因此要重写onTouchEvent(MotionEvent ev),其中移动过程实际上是将菜单view按照移动的方向和距离,怎么实现这个功能呢?源码中最关键的就是这行代码

inner.layout(inner.getLeft(), yy, inner.getRight(),inner.getBottom() - deltaY);这个方法四个参数都是inner相对其父控件ScrollView的坐标原点而言的。不是很了解的,可以专门查查坐标的相关知识。

    2.3当手指抬起也就是MotionEvent.ACTION_UP事件发生时,将拖拽后的view恢复移动到原来位置,移动过程附加了一个动画,由于移动实际上是位置发生了变化,因此用到了TranslateAnimation,因为是上下拖拽,所以X的起始和终止坐标都是0,Y的起始和终止坐标至于为什么那么写,相信看完博客应该就会明白了。那么问题来了,要自动移动回去,那么触发的时机在MotionEvent.ACTION_UP中,原来的位置怎么保存,因为移动时需要左上右下四个参数,因此在CustomerScrollView中我们看到了这样一个变量private Rect normal = new Rect();通过

normal.set(inner.getLeft(), inner.getTop(),inner.getRight(), inner.getBottom());方法记录菜单view的初始化位置。

    2.4在源码中这个函数也值得我们去分析下:

//是否需要移动

public boolean isNeedMove() {

int offset = inner.getMeasuredHeight() - getHeight();

int scrollY = getScrollY();

if (scrollY == 0 || scrollY == offset) {

return true;

}

return false;

}

    经过仔细揣摩发现scrollY == 0这个条件实际上是滚动到了最顶部的时候,而scrollY == offset是滚动到最底部的时候,两个条件满足其中一个都可以实现拖拽的效果。int offset = inner.getMeasuredHeight() - getHeight();相当于本身的身高减去实际能看到的身高就等于没有看到的身高部分。

    2.5为什么源码中需要isNeedAnimation()这个函数呢?因为恢复到原来位置也用到了inner.layout(normal.left, normal.top, normal.right, normal.bottom);,因此normal首先必须要有四个参数值。而这个normal只有满足2.4中的条件后才有值的。

   2.6为什么在拖拽发生又恢复到原来位置后,要把这个normal.setEmpty();置空呢?它的意图是什么?仔细想来,发现这个normal的set左上右下四个值时,是在满足2.4两种条件之一就会有具体值的。因此这个normal就会有两种不同的Rect.顶部的时候左上右下四个值分别为(0,0,实际菜单的宽度240dp,菜单的实际测量高度)而滚动到最底部的时候左上右下四个值分别为(0,负的【菜单的实际高度减去屏幕的高度】,实际菜单的宽度240dp,屏幕的高度),因此需要清空。





   

© 著作权归作者所有

姬鑫
粉丝 85
博文 54
码字总数 16632
作品 0
宁波
程序员
私信 提问
加载中

评论(1)

九洲北研
九洲北研
愿意学习。愿意提高的兄弟们。一起研究开源中国客户端源码。群号324386394。验证开源中国
开源中国 OsChina Android 客户端源码分析(2)滑动菜单DrawerLayout

1滑动菜单oschina使用了android.support.v4.widget.DrawerLayout,之前没有用过这个控件,百度了下,大致了解如下: 1.1类似与LinearLayout,就是一个布局控件。 1.2使用时,其有两部分组成,...

姬鑫
2015/05/20
1K
3
开源中国安卓客户端更新,支持语音动弹

这是 OSCHINA 官方开发的 Android 客户端软件,采用原生 API 开发,非 HTML 模式。 开源中国安卓客户端 v1.7.6.4 版更新资讯: OSChina.NET for Android v1.7.6.4 更新日志: 1、语音动弹发布...

火蚁
2014/02/11
4.3K
54
react native 基础(二)

一.JSON输出(列表输出) let appData=require("./appData.json"); //导入JSON文件 export default class ReacrtNativeProject extends Component {render() { } returnAllBao(){ }} 二.TextIn......

Chason-洪
2017/07/21
0
0
开源中国码云客户端新版发布

duang duang duang …… 开源中国码云客户端Git@OSC今天发布新版! 码云客户端iOS最新版本:1.2.2 码云客户端Android最新版:1.5.3 本次给大家带来的新版变化内容如下: 修复部分项目的详情无...

巴拉迪维
2016/05/13
8.8K
16
求解疑/建议:关于Android、组态软件、根据URL解析出标题/正文内容 等的问题

求解疑/建议:关于Android、组态软件、根据URL解析出标题/正文内容 等的问题 因为这关系到我能否有机会继续升读本科继续学习(我现在是专科),盼各位前辈多多指点! 简易安卓客户端新闻发布...

wkl17
2014/03/31
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。 比较通用的返回值格式如下:...

晓月寒丶
今天
58
0
区块链应用到供应链上的好处和实际案例

区块链可以解决供应链中的很多问题,例如记录以及追踪产品。那么使用区块链应用到各产品供应链上到底有什么好处?猎头悬赏平台解优人才网小编给大家做个简单的分享: 使用区块链的最突出的优...

猎头悬赏平台
今天
27
0
全世界到底有多少软件开发人员?

埃文斯数据公司(Evans Data Corporation) 2019 最新的统计数据(原文)显示,2018 年全球共有 2300 万软件开发人员,预计到 2019 年底这个数字将达到 2640万,到 2023 年达到 2770万。 而来自...

红薯
今天
61
0
Go 语言基础—— 通道(channel)

通过通信来共享内存(Java是通过共享内存来通信的) 定义 func service() string {time.Sleep(time.Millisecond * 50)return "Done"}func AsyncService() chan string {retCh := mak......

刘一草
今天
57
0
Apache Flink 零基础入门(一):基础概念解析

Apache Flink 的定义、架构及原理 Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态或无状态的计算,能够部署在各种集群环境,对各种规模大小的数据进行快速...

Vincent-Duan
今天
50
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部