Android Scroller的使用方法

作者:吹白 时间:2023-02-03 03:57:01 

本文实例为大家分享了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()
       }
   }
}

运行结果:

Android Scroller的使用方法

来源:https://blog.csdn.net/u013028621/article/details/116935101

标签:Android,Scroller
0
投稿

猜你喜欢

  • JVM类加载,垃圾回收

    2022-08-16 02:44:36
  • C#将Excel转成PDF的方法

    2021-06-13 01:46:09
  • Mybatis结果集自动映射的实例代码

    2023-07-09 02:13:58
  • Android模拟实现支付宝蚂蚁森林效果

    2023-03-15 05:07:38
  • SpringBoot集成Tomcat服务架构配置

    2022-06-30 09:10:11
  • C#设置与获取环境变量的方法详解

    2021-09-03 20:55:29
  • java设计模式理解依赖于抽象不依赖具体的分析

    2023-09-13 01:41:45
  • Android TextView自定义数字滚动动画

    2023-10-03 09:48:17
  • java 如何读取远程主机文件

    2022-03-23 05:18:19
  • C#使用GDI+实现生成验证码

    2023-04-10 10:42:44
  • java实现上传网络图片到微信临时素材

    2022-09-21 08:43:23
  • 从字符串中截取等长字节的Java代码

    2023-03-12 10:11:41
  • C# Cache缓存读取的设置方法

    2022-11-18 05:33:53
  • java IO实现电脑搜索、删除功能的实例

    2021-12-17 07:16:14
  • SpringBoot如何通过Feign调用传递Header中参数

    2023-11-24 21:39:29
  • ReadWriteLock接口及其实现ReentrantReadWriteLock方法

    2023-11-24 01:46:52
  • Java语法基础之循环结构语句详解

    2023-09-06 21:37:28
  • java中Path和ClassPath用法比较

    2022-03-15 03:41:26
  • WPF使用Geometry绘制几何图形

    2023-08-14 14:13:31
  • java 避免出现NullPointerException(空指针)的方法总结

    2022-08-31 04:15:51
  • asp之家 软件编程 m.aspxhome.com