「Android View系列」2.View的滑动

459 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

上一篇View系列文章介绍了View的基础知识,坐标系与点坐标的计算方式,这些对后面自定义View是非常重要的知识点。本篇来学习View的滑动,当下移动设备上,滑动操作算是应用的标配,下拉刷新,手机屏幕的全面屏手势等的基础都是滑动。View滑动的丝滑性是后面自定义控件的基础,那Android中实现滑动的常见方式有哪些?

本文总览

View的滑动.png

1.滑动的重要性

对于现在的Android移动设备来说,由于屏幕尺寸限制,要给用户展示更多内容,APP应用就需要使用滑动来隐藏和显示部分内容;

另一点,滑动效果现在算是移动应用的标配了,下拉刷新和上拉加载等这些操作都是基于View滑动。

自定义控件的炫酷效果都是基于View的滑动,上述的几点就可以知道滑动在应用开发中的重要性。

2.View的滑动方式

2.1 layout方法改变view的位置

学习过View源码肯定知道,在处理触摸事件时,系统会调用layout(int l, int t, int r, int b) 方法来获取到View的位置。同样也可以修改四个参数的值控制View的位置。

    // 视图坐标方式
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        ...
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 记录触摸点坐标
                ...
                break;
            case MotionEvent.ACTION_MOVE:
                // 计算偏移量
                int offsetX = x - lastX;
                int offsetY = y - lastY;
                // 在当前left、top、right、bottom的基础上加上偏移量
                layout(getLeft() + offsetX,
                       getTop() + offsetY,
                       getRight() + offsetX,
                       getBottom() + offsetY);
                break;
        }
        return true;
    }

从源码中可知,在处理ACTION_MOVE事件,首先计算出X Y偏移量 offsetXoffsetY 再调用layout()确定View变更后的位置。

2.2 使用scrollTo/scrollBy

View的源码中专门提供了方法scrollTo/scrollBy来实现滑动,先来看看代码实现

public void scrollTo(int x,int y) { 
    if (mScrollX != x || mScrollY != y) { 
        int oldX = mScrollX; 
        int oldY = mScrollY; 
        mScrollX = x; 
        mScrollY = y; 
        invalidateParentCaches(); 
        ... //逻辑处理
    }
}

public void scrollBy(int x,int y) {
    // 调用 scrollTo方法
    scrollTo(mScrollX + x,mScrollY + y); 
}

从上述源码来看,scrollBy 实际上也是调用 scrollTo 方法,实现了基于当前位置的相对滑动;而 scrollTo 则实现了基于参数的绝对滑动。 可以看到源码中的两个属性 mScrollXmScrollY 是分别通过 getScrollXgetScrollY方法得到。 这里需要概括说明下:在滑动过程中,mScrollX的值总是等于View左边缘和View内容左边缘 在水平方向的距离,而mScrollY的值总是等于View上边缘和View内容上边缘在竖直方向的距离

scollby 滑动.png 值得注意的是:使用scrollTo和scrollBy来实现View的滑动,只能将View的内容进行移动,并不能将View本身进行移动

2.3 使用动画

说到动画,肯定会想到平移,旋转等方式。这里借用 平移动画 来讲述。View 平移其实就是滑动,主要是操作View 的translationXtranslationY属性,另外Android3.0以后,还引入了 属性动画,它不仅可以作用View滑动操作,还可以作用于 属性来产生动画效果。

ObjectAnimator.ofFloat(testScroll, "translationX", 0, 300)
              .setDuration(2000) // 动画持续时间
              .start(); // 开启

属性动画相较于 补间动画更加地灵活,真正实现View的位置。进一步的知识会在Android动画专题,深入学习。

2.4 改变布局参数

在定义View时,常会碰到一个对象 LayoutParams,所说的改变布局参数指的就是更改LayoutParams

ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) getLayoutParams();
layoutParams.leftMargin = getLeft() + offsetX;
layoutParams.topMargin = getTop() + offsetY;
setLayoutParams(layoutParams);

这个其实比较好理解,修改了位置参数那View的实际位置肯定变化。这同样是较为灵活的方式,根据不同的需求进行不同的处理。

3.各种滑动方式对比

上面介绍了四种不同的方式,都可以来实现View的滑动。那它们之间有什么差异点呢?

  • 使用layout方法实现view滑动
    • 优点:真实改变了View的位置而不只是View的内容
    • 缺点:较为复杂
  • scrollTo/scrollBy实现滑动
    • 优点:是View提供的原生方法,操作简单,适合对View内容的滑动
    • 缺点:只能滑动View的内容,并不能滑动View本身
  • 使用动画
    • 优点:操作简单,主要适用于没有交互的View和实现复杂的动画效果
    • 缺点:不能改变View本身的属性
  • 修改LayoutParams参数
    • 优点:适用于有交互的View
    • 缺点:操作稍微复杂

总结

View的滑动方式种类还是不较多的,日常项目开发中视业务场景选择最适合的方式就行。

后面还会有针对于各个知识点做更详尽的解析。

掘金(JUEJIN)一起进步!