Android-ScrollView

本贴最后更新于 3228 天前,其中的信息可能已经东海扬尘

项目中有用到一个类似于日期时间的滑动选择控件,然而感觉 android 自带的 DataPicker 与 app 的整体风格不太一样,于是想着自己写一个超级简洁美丽大方的控件出来。

本来想到滑动选择,就想到了 scrollview,然后在网上搜了一下,谁想到网上资料全都是一样的。。一点营养都没有,虽然最后由于 API 版本的原因没有采用 scrollview 的方式,但是中间对其研究了一下,特此分享。


ScrollView基本用法介绍

ScrollView的主要用处是,当你在一个界面上显示的内容超过了display大小的时候,用scrollview滑动显示,比如大众点评一些app的主页面。这里还要提一下ScrollView里用到了很多次Nest,这是为什么?

因为Nest是嵌套的意思,个人认为ScrollView的设计初衷是嵌套在整个Display中,如果你创建一个带ActionBar的Activity,就会发现,向下滑动ScrollView,ActionBar会自动消失,向上滑动则会出现。
用法:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_gravity="center"
    android:layout_width="100dp"
    android:layout_height="80dp" tools:context=".MainActivity">
    <LinearLayout
        android:id="@+id/scrollview"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TextView
            android:id="@+id/text"
            android:text="2010"
            android:textSize="30dp"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/text23"
            android:text="2010"
            android:textSize="30dp"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</ScrollView>

这里要注意,ScrollView只能有一个childview,一般用一个LinearLayout来实现,在LinearLayout中添加其他控件。


ScrollView初始化

ScrollView继承FrameLayout,所以等级和LinearLayout这些是一样的,初始化也大同小异,无非就是传递一些attr和style的值,这里有几个变量介绍一下,在initScrollView()中


       
 mTouchSlop = configuration.getScaledTouchSlop();
        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
        mOverscrollDistance = configuration.getScaledOverscrollDistance();
        mOverflingDistance = configuration.getScaledOverflingDistance();


mTouchSlop是触摸溢出极限值了,这个在后面onTouch里会提到
Velocity是速率的意思,fling是掷的意思,我理解为手指在屏幕上的快速滑动
Touch行为

和其他View的Touch一样,先传给onTouchEvent之前,传递给onInterceptTouchEvent函数,首先*ACTION.DOWN*行为,


       
 if (actionMasked == MotionEvent.ACTION_DOWN) {
            mNestedYOffset = 0;
        }
        vtev.offsetLocation(0, mNestedYOffset);


记录mNestedYOffset,Y方向上的offset


case MotionEvent.ACTION_DOWN: {
                if (getChildCount() == 0) {
                    return false;
                }
                if ((mIsBeingDragged = !mScroller.isFinished())) {
                    final ViewParent parent = getParent();
                    if (parent != null) {
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                }
            /*
             * If being flinged and user touches, stop the fling. isFinished
             * will be false if being flinged.
             */
            if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
                if (mFlingStrictSpan != null) {
                    mFlingStrictSpan.finish();
                    mFlingStrictSpan = null;
                }
            }


            // Remember where the motion event started
            mLastMotionY = (int) ev.getY();
            mActivePointerId = ev.getPointerId(0);
            startNestedScroll(SCROLL_AXIS_VERTICAL);
            break;</pre>


这里会检测到ScrollView是否正在被拉动,如果没有被拉动,就停止动画
同时得到mLastMotionY,就是手指按下的位置
还有mActivePointerId,这里的Pointer可以当做手指产生的trace代号,如果有multi-touch,就会有多个pointer,在这里不是重点,不细说。


接下来是*ACTION_MOVE*


      
   final int y = (int) ev.getY(activePointerIndex);
         int deltaY = mLastMotionY - y;
         if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
                 deltaY -= mScrollConsumed[1];
                 vtev.offsetLocation(0, mScrollOffset[1]);
                 mNestedYOffset += mScrollOffset[1];
         }


deltaY大家都能看懂,重点是dispatchNestedPreScroll(0,deltaY,mScrollConsumed,mScrollOffset)这个函数,先说一下后两个参数的意义,mScrollConsumed就是Parent消耗的滑动的部分(其实我不太明白为什么会有这个参数,是为了让滑动不要太敏感吗?但是我们可以从这个参数知道,我们最终ScrollView滑动的距离是由parent消耗的一部分和真正的滑动的一部分所组成的),第4个参数就是scrollview已经产生的offset了。这个函数名字叫做PreScroll,我们也可以知道这是预滑动,也就是childview还没有开始滑动前做的动作。
在这个函数里做了什么呢?
其实调用了mNestedScrollingParent.onNestedPreScroll,也就是parent的prescroll,然后产生一个consumed和offset传递回来。
返回之后,我们可以看到deltaY-mScrollConsumed[1]得到的就是真正的childview所需要滑动的deltaY了,然后记录下来。


其实后面的代码也和上面类似,就不做多解释了。看完这个,你应该对ScrollView有了一个大致的了解,之后运用起来相信会更加的娴熟。


千万要记住一点,不要在ScrollView中嵌套上已经具有Scroll功能的控件里,比如ListView,比如装载不下的TextView。





  • ScrollView
    3 引用
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    334 引用 • 323 回帖 • 25 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    28 引用 • 108 回帖
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    285 引用 • 4482 回帖 • 659 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 2 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 19 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 705 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    7 引用 • 26 回帖
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    83 引用 • 165 回帖 • 11 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 5 关注
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    69 引用 • 190 回帖 • 484 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 644 关注
  • gRpc
    10 引用 • 8 回帖 • 51 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    安卓端仓库:Hi-Windom/Sillot-android

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    28 引用 • 25 回帖 • 56 关注
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4599 回帖 • 689 关注
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 139 关注
  • V2Ray
    1 引用 • 15 回帖 • 1 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 434 关注
  • Kafka

    Kafka 是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是现代系统中许多功能的基础。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。

    35 引用 • 35 回帖 • 3 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 2 关注
  • 博客

    记录并分享人生的经历。

    272 引用 • 2386 回帖
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 476 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 65 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    60 引用 • 287 回帖
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 27 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    207 引用 • 358 回帖
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 2 关注