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()
}
}
}
运行结果:
来源:https://blog.csdn.net/u013028621/article/details/116935101


猜你喜欢
- java 中 * 机制的实例讲解在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,
- 在做项目时经常会遇到选择本地图片的需求,以前都是懒得写直接调用系统方法来选择图片,但是这样并不能实现多选效果,最近又遇到了,所以还是写一个d
- 演示1 - 代理创建器public class A17 { public static void main(Str
- 一、什么是桥接模式:桥接,顾名思义,就是用来连接两个部分,使得两个部分可以互相通讯,桥接模式的作用就是为被分离的抽象部分和实现部分搭桥。在现
- 自定义转换器实现参数去空格1.自定义转换器类实现Converter<S, T>类,重写convert()方法,直接上代码。/**
- Java提供的数据类型主要分为两大类:基本数据类型和引用数据类型。Java中的基本数据类型名称大小取值范围byte型 (字节)8bit-12
- 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对,例如在数组{7,5,6,4}中,一共存在5对逆序对,分别是{
- 几点重要的用法:a 先来介绍几个方法TimeSpan.Minutes(其他时间比如天数,小时数,秒数都一样的情况下得到的分钟数的差),其他的
- maven打包方式使用maven打包插件maven-jar-plugin在pom.xml文件最后新增以下代码。maven-dependenc
- 题记:由于业务的需要,需要根据模板定制pdf文档,经测试根据模板导出word成功了;但是导出pdf相对麻烦了一点。两天的研究测试java导出
- 引言:在使用循环的时候,循环里面带有break、continue、return的时候经常弄混,今天特意整理了下,以待后用... f
- 本文实例为大家分享了Android TextView图文混合编排的具体代码,供大家参考,具体内容如下实现技术细节不难,两个要点:1、html
- Spring 提供了自动代理机制,可以让容器自动生成代理,从而把开发人员从繁琐的配置中解脱出来 。 具体是使用 BeanPostProces
- 引言在前两篇文章中,我们了解了ReentrantLock内部公平锁和非公平锁的实现原理,可以知道其底层基于AQS,使用双向链表实现,同时在线
- 前言含义:(1)多重循环指一个循环语句的循环体中再包含循环语句,又称嵌套循环。(2)循环语句内可以嵌套多层循环。(3)不同的循环语句可以相互
- 第一种方式(只使用Caffeine)gradle添加依赖dependencies { implementation
- package com.chen.lucene.image;import java.io.File;import java.io.FileI
- POM<dependency> <groupId>org.springframework.boot<
- 动态SQL实现前端指定返回字段问题描述在使用ClickHouse时,遇到需要根据业务需求,动态返回指定字段,从而充分利用ClickHouse
- unity3d发布apk在android虚拟机中运行的详细步骤(unity3d导出android apk),总的流程分为以下6个步骤:1、安