博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Android UI]View滑动方式总结
阅读量:5367 次
发布时间:2019-06-15

本文共 4636 字,大约阅读时间需要 15 分钟。

一、前言

  在上一篇文章,介绍了View的坐标等基础知识,有了基础知识后,对下面内容的理解也将会容易很多。那么本文介绍的是View滑动的几种方式,这对于View来说,也是需要重要掌握的内容,因为用户无时无刻不在与View打交道,而主要途径有滑动,比如说:界面的切换等。

二、滑动方式

  在Android中,要滑动一个View有多种方式,下面就来介绍几种常用的方式以及他们的区别。

1、使用scrollTo或scrollBy

  在View的源码中,提供了专门滑动View的方法,分别是scrollTo和scrollBy。顾名思义,scrollTo是滑动到某一坐标,是绝对滑动;而scrollBy是滑动一段距离,是相对滑动。而需要特别注意的是,这里用的两个方法,都是只改变View的内容的位置,实际上View的坐标并没有改变。为了说明这个问题,我们来看一下源码:

/**      * The offset, in pixels, by which the content of this view is scrolled      * horizontally.      * {@hide}      */        @ViewDebug.ExportedProperty(category = "scrolling")        protected int mScrollX;        protected int mScrollY;    /**      * Set the scrolled position of your view. This will cause a call to      * {@link #onScrollChanged(int, int, int, int)} and the view will be      * invalidated.      * @param x the x position to scroll to      * @param y the y position to scroll to      */        public void scrollTo(int x, int y) {            if (mScrollX != x || mScrollY != y) {                int oldX = mScrollX;                int oldY = mScrollY;                mScrollX = x;                mScrollY = y;                invalidateParentCaches();                onScrollChanged(mScrollX, mScrollY, oldX, oldY);                if (!awakenScrollBars()) {                    postInvalidateOnAnimation();                }            }        }    /**      * Move the scrolled position of your view. This will cause a call to      * {@link #onScrollChanged(int, int, int, int)} and the view will be      * invalidated.      * @param x the amount of pixels to scroll by horizontally      * @param y the amount of pixels to scroll by vertically      */        public void scrollBy(int x, int y) {            scrollTo(mScrollX + x, mScrollY + y);        }

  实际上scrollBy调用了scrollTo方法,我们只看scrollTo方法,在方法内部,没有涉及到我们上一篇文章说到了View的几个基本参数,而是使用了mScrollX、mScrollY这两个参数,那这两个参数表示的是什么呢?从源码的注释我们可以看出,这两个坐标是表示View内容的偏移量,并且单位是px,即mScrollX是等于View的左边缘和View内容左边缘在水平方向的距离,并且当View内容左边缘在View左边缘的右侧的时候,mScrollX为负,反之为正;同理,mScrollY是等于View的上边缘和View内容上边缘在数值方向的距离,并且Viwe内容上边缘在View上边缘下侧的时候,mScrollY为负,反之为正。为了方便理解,下面用几幅图描述mScrollX、mScrollY和View内容的关系:

1240

  小结一下:对于View内容来说,从左往右滑,mScrollX为负;从上往下滑,mScrollY为负。

  那么,View和View内容有什么关系呢?可以这样想,对于一个View来说,是一个容器,而View内容是容器里面的东西。对于一个ViewGroup来说,那么它的内容是它的所有子View,那么如果在ViewGroup调用了scrollTo或者scrollBy,它的所有子View会同时移动。对于一个具体的View来说,比如说一个TextView,它的内容就是它里面的文字;对于一个ImageView,它的内容就是它里面的图片,诸如此类。

  这里给出滑动一个View的使用方法:

TextView textview = (TextView) findViewById(R.id.textview);    textview.scrollBy(-20,0)      //将textview里面的文字向右滑动20px

  总之,使用scrollTo和scrollBy滑动一个View的时候,View的布局参数(比如Top、Left、X、Y等)不会改变,改变的是View的内容位置。

2、使用属性动画

  使用Android 3.0推出的属性动画,可以很轻松实现一个View的滑动:

ObjectAnimator.ofFloat(view,"translationX",0,100).setDuration(500).start();

  对ofFloat方法的几个参数解释:第一个参数是要滑动的view;第二个参数是对view的某个参数进行改动,这里选择translationX,那么动画效果将作用于view的translationX参数,上一篇文章说到translationX代表view的偏移量,所以属性动画改变的是translationX和translationY值,而不是初始的Top、Left等值;最后两个参数表示前一个参数的起始值和最终值,这里指定为0和100,意思就是说translationX从0变到100。由于涉及到了View的基本参数,所以属性动画这种滑动方式改变的是View本身的位置。

3、改变布局参数

  顾名思义,这个方法是直接对View的位置参数进行改变,即改变LayoutParams,下面给出一个示例再进行分析:

ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) imageView.getLayoutParams();  //获取imageView的布局参数    params.leftMargin += 100;     //修改leftMargin的值,相当于xml布局文件中的margin_left的值    imageView.setLayoutParams(params);  //将新的params值设置进imageView

  这里说明一下,对布局参数的改变,实际上是改变了View的top、left、right、bottom这四个初始坐标;然而在上一篇文章有说到,View在绘制完成后这四个初始值是不会改变的,那么是否是矛盾了呢?其实不是的,实际上setLayoutParams()对布局参数的改变,会触发View的重新测绘、布局、绘制这三个流程,那么这四个值也就随之改变了,关于View的三大工作流程,这里不详谈了,以后可能写View机制的源码分析的文章。

4、使用layout()

  View在绘制的时候会调用layout()来确定View本身的位置,那么我们可以直接调用这个方法来绘制View:

viwe.layout(int left,int top,int right,int bottom);

  一行代码即可调整View的位置了,注意到,以上都是view相对于父容器的坐标,View的位置的确定依赖于这四个坐标,如果这四个坐标不按照view自身的缩放比例设置,会造成View制图的缩放。比如说,一个View的宽和高都是100,选择的位移坐标是(50,50,100,100),那么显然view的宽和高就变成了50,即缩小了。所以如果为了View的正常滑动,一般可以将以上代码修改成如下:

view.layout(view.getLeft()+offsetX,view.getTop()+offsetY,view.getRight()+offsetX,view.getBottom()+offsetY);

5、使用 offsetLeftAndRight 和 offsetTopAndBottom

  直接调用View的offsetLeftAndRight(int offsetX)或者offsetTopAndBottom(int offsetY)能对view的四个坐标直接进行偏移,以达到移动view的目的。

imageView.offsetLeftAndRight(50);  //将imageView沿水平正方向偏移50px    imageView.offsetTopAndBottom(50); //将iamgeView沿竖直正方向偏移50px

  原理和onlayout方法差不多,也是导致了view的重新布局、绘制,所以基本参数坐标发生了变化。

三、总结

  以上介绍了5种常见的view滑动方式,其实还有一种:scroller,这个将会在下一篇文章的弹性滑动中讲述这个类的用法,这里先总结上面说到的5种滑动方式的应用场景:

  ①scrollTo/scrollBy:只适合对view的内容的滑动

  ②属性动画:操作简单,功能强大,能实现复杂的动画效果,不建议用于有交互的View

  ③布局参数、layout、offsetLeftAndRight:适用于交互性强的View,对View的绘制原理应该有一定理解,这样使用的时候才会得心应手。

转载于:https://www.cnblogs.com/zhousysu/p/5616307.html

你可能感兴趣的文章
挂载U盘到linux中
查看>>
怎么获得combobox的valueField值
查看>>
Quartz.net 开源job调度框架(二)----定点执行
查看>>
WPF中内嵌网页的两种方式
查看>>
人生么
查看>>
[再寄小读者之数学篇](2014-11-14 正整数的平方根要么为无理数, 要么为整数)
查看>>
为新生儿办理户口
查看>>
Bootstrap 中 下拉菜单和滚动监听插件(十一)(持续更新中。。。)
查看>>
团队-科学计算器-项目总结
查看>>
python 发邮件
查看>>
Python3:输出当前目录所有文件的第二种方式-walk()函数
查看>>
每日算法 ---- 求1!+2!+3!+......+20!的值
查看>>
nodejs 全局变量-global
查看>>
复制参数优化
查看>>
日期选择器
查看>>
关于NHibernate、LINQ、Entity Framework
查看>>
查看库文件中的接口
查看>>
acid. cap
查看>>
Rewrite MSIL Code on the Fly with the .NET Framework Profiling API
查看>>
O-C相关-06:对象与对象的关系
查看>>