Android Scroller的使用方法

本文实例为大家分享了Android Scroller的使用方法,供大家参考,具体内容如下

1、scrollTo和ScrollBy

View类定义了两个用于滚动View内容的方法:scrollTo和scrollBy:

/**
 * 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传入的x和y参数实际上是X方向和Y方向的滚动距离的增量,最终还是调用了scrollTo方法。而scrollTo方法中做了一些刷新和通知操作,最重要的是对mScrollX和mScrollY进行了赋值。

在View的draw方法中,我们可以看到如下代码:

int sx = 0;
int sy = 0;
if (!drawingWithRenderNode) {
    computeScroll();
    sx = mScrollX;
    sy = mScrollY;
}

...

if (offsetForScroll) {
    canvas.translate(mLeft - sx, mTop - sy);
}

也就是说,mScrollX和mScrollY最终是用在了内容绘制的地方,其mLeft和mTop本身都没有因为scrollTo发生变化。scrollTo作用在View的内容上,而不是View本身。

2、 computeScroll

在上面的View的draw方法的节选中我们看到在对mScrollX和mScrollY取值之前,调用了computeScroll方法。computeScroll方法声明如下:

/**
 * Called by a parent to request that a child update its values for mScrollX
 * and mScrollY if necessary. This will typically be done if the child is
 * animating a scroll using a {@link android.widget.Scroller Scroller}
 * object.
 */
public void computeScroll() {
}

根据注释,computeScroll的典型用法是与Scroller结合使用实现内容/字节点的滚动动画。

3、Scroller的使用

Scroller事实上并不直接操作View的滚动,而是根据设置来计算当前X和Y方向的距离。Scroller的一般使用步骤:

1、初始化Scroller,可以指定插值器,不指定则使用默认的ViscousFluidInterpolator
2、调用Scroller#startScroll方法,开始在一段时间内不断计算X和Y方向的滚动
3、通知View刷新
4、在View#computeScroll中通过scrollTo实现真正的滚动操作
5、通知View刷新

其中在滚动执行完成之前4和5会不断地循环,直至scroller.computeScrollOffset()返回false。

class ScrollableLinearLayout @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
    private val scroller = Scroller(context, BounceInterpolator())

    override fun computeScroll() {
        if(scroller.computeScrollOffset()) {
            // 真正实现滚动操作的地方
            scrollTo(scroller.currX, scroller.currY)

            // 刷新
            invalidate()
        }
    }

    fun scroll() {
        // 调用Scroller的startScroll
        if(scrollX == 0) {
            scroller.startScroll(scrollX, scrollY, /*dx*/ -500, /*dy*/ 0, /*duration*/ 300)
        } else {
            scroller.startScroll(scrollX, scrollY, 500, 0, 300)
        }

        // 刷新
        invalidate()
    }

}

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".scroller.activity.ScrollerSampleActivity">

    <com.sahooz.customviewdemo.scroller.view.ScrollableLinearLayout
        android:id="@+id/sll"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:gravity="center_vertical"
        android:orientation="vertical"
        android:background="#FFAAAA">

        <Button
            android:id="@+id/btnScroll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Scroll" />

    </com.sahooz.customviewdemo.scroller.view.ScrollableLinearLayout>

</LinearLayout>

Activity

class ScrollerSampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_scroller_sample)

        val btnScroll = findViewById<Button>(R.id.btnScroll)
        btnScroll.setOnClickListener {
            findViewById<ScrollableLinearLayout>(R.id.sll).scroll()
        }
    }
}

运行结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • android使用 ScrollerView 实现 可上下滚动的分类栏实例

    如果不考虑更深层的性能问题,我个人认为ScrollerView还是很好用的.而且单用ScrollerView就可以实现分类型的RecyclerView或ListView所能实现的效果. 下面我单单从效果展示方面考虑,使用ScrollerView实现如下图所示的可滚动的多条目分类,只是为了跟大家一起分享一下新思路.(平时:若从复用性等方面考虑,这显然是存在瑕疵的~) 特点描述: 1.可上下滚动 2.有类似于网格布局的样式 3.子条目具有点击事件 刚看到这个效果时,首先想到的是使用分类型的Recyc

  • 深入理解Android中Scroller的滚动原理

    View的平滑滚动效果 什么是实现View的平滑滚动效果呢,举个简单的例子,一个View从在我们指定的时间内从一个位置滚动到另外一个位置,我们利用Scroller类可以实现匀速滚动,可以先加速后减速,可以先减速后加速等等效果,而不是瞬间的移动的效果,所以Scroller可以帮我们实现很多滑动的效果. 首先我们先来看一下Scroller的用法,基本可概括为"三部曲": 1.创建一个Scroller对象,一般在View的构造器中创建: public ScrollViewGroup(Cont

  • 详解Android Scroller与computeScroll的调用机制关系

    Android ViewGroup中的Scroller与computeScroll的有什么关系? 答:没有直接的关系 知道了答案,是不是意味着下文就没必要看了,如果说对ViewGroup自定义控件不感兴趣,可以不用看了. 1.Scroller到底是什么? 答:Scroller只是个计算器,提供插值计算,让滚动过程具有动画属性,但它并不是UI,也不是滑动辅助UI运动,反而是单纯地为滑动提供计算. 无论从构造方法还是其他方法,以及Scroller的属性可知,其并不会持有View,辅助ViewGrou

  • Android使用Scroller实现弹性滑动效果

    本文实例为大家分享了Android使用Scroller实现弹性滑动展示的具体代码,供大家参考,具体内容如下 scrollTo.scrollBy View内部为了实现滑动提供了这两个方法,但是使用这两个方法滑动的效果是瞬间的不够平滑,如何实现View的弹性滑动呢?这正是本博文讨论的主题.另外这两个函数滑动的是View的内容不是View本身.比如对于普通View好比TextView其内容就是文本,ImageView的内容则是drawable对象,采用这两种方法滑动的时候其实分别滑动的是文本及draw

  • Android Scroller大揭秘

    在学习使用Scroller之前,需要明白scrollTo().scrollBy()方法. 一.View的scrollTo().scrollBy() scrollTo.scrollBy方法是View中的,因此任何的View都可以通过这两种方法进行移动.首先要明白的是,scrollTo.scrollBy滑动的是View中的内容(而且还是整体滑动),而不是View本身.我们的滑动控件如SrollView可以限定宽.高大小,以及在布局中的位置,但是滑动控件中的内容(或者里面的childView)可以是无

  • Android用Scroller实现一个可向上滑动的底部导航栏

    静静等了5分钟竟不知道如何写我这第一篇文章.每次都想好好的学习学习,有时间多敲敲代码,写几篇自己的文章.今天终于开始实行了,还是有点小激动的.哈哈! 好了废话就不多收了.我今天想实现的一个功能就是一个可以上滑底部菜单栏.为什么我会想搞这么个东西呢, 还是源于一年前,我们app 有这么个需求,当时百度也好谷歌也好,都没有找到想要的效果,其实很简单的一个效果.但是当时我也是真的太菜了,所有有关自定义的控件真的是不会,看别人的代码还好,真要是自己写,一点头绪都没有.因为我试着写了,真的不行啊.当时觉得

  • Android Scroller完全解析

    在Android中,任何一个控件都是可以滚动的,因为在View类当中有scrollTo()和scrollBy()这两个方法,如下图所示: 这两个方法的主要作用是将View/ViewGroup移至指定的坐标中,并且将偏移量保存起来.另外: mScrollX 代表X轴方向的偏移坐标 mScrollY 代表Y轴方向的偏移坐标 这两个方法都是用于对View进行滚动的,那么它们之间有什么区别呢?简单点讲,scrollBy()方法是让View相对于当前的位置滚动某段距离,而scrollTo()方法则是让Vi

  • Android Scroller及下拉刷新组件原理解析

    Android事件拦截机制 Android中事件的传递和拦截和View树结构是相关联的,在View树中,分为叶子节点和普通节点,普通节点有子节点只能是ViewGroup,叶子节点可以是View或者ViewGroup.Android和事件分发拦截相关的方法有 dispatchTouchEvent(MotionEvent ev) 事件分发相关的方法,沿着View树将一个用户的触摸事件向下分发. onInterceptTouchEvent(MotionEvent ev) 在dispatchTouchE

  • Android程序开发之UIScrollerView里有两个tableView

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController : UIViewController <UIScrollViewDelegate,UITableViewDelegate,UITableViewDataSource> { UIScrollView *_scrolView; UITableView *_tableView; UITableView

  • 详解Android应用开发中Scroller类的屏幕滑动功能运用

    今天给大家介绍下Android中滑屏功能的一个基本实现过程以及原理初探,最后给大家重点讲解View视图中scrollTo 与scrollBy这两个函数的区别 .   首先 ,我们必须明白在Android View视图是没有边界的,Canvas是没有边界的,只不过我们通过绘制特定的View时对Canvas对象进行了一定的操作,例如 : translate(平移).clipRect(剪切)等,以便达到我们的对该Canvas对象绘制的要求 ,我们可以将这种无边界的视图称为"视图坐标"----

随机推荐