本文主要是介绍View的滑动之ScrollTo和ScrollBy,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目前View滑动的实现方式主要有三种:
1.通过View自身提供的ScrollTo和ScrollBy。
2.通过动画来使View平移来实滑动。
3.第三种是通过改变View的LayoutParams,使View重新布局实现滑动。
这几天在看View的滑动,虽然ScrollTo和ScrollBy在实际的开发过程中用到的很少,特别是属性动画的广泛运用后,既然存在,必有价值。
所以在这里将ScrollTo和ScrollBy简单分析一下:
先看一下ScrollTo的源码:
/*** 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();}}}
再看看ScrollBy的源码:
/*** 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呢,他们的区别就在于ScrollBy方法中调用ScrollTo时将传递的参数加上了当前 View内容到View边缘位置的距离 (mScrollX、mScrollY)。
关于mScrollTo和mScrollBy这里我是这样理解的:
mScrollX 是View左边缘与View内容左边缘的水平方向上的距离,理解为View左边缘X坐标减去View内容左边缘X坐标。
mScrollY 是View顶部与View内容上边缘的在竖直方向上的距离,理解为View顶部Y坐标减去View内容顶部Y坐标。
我们用两幅图来表示:绿色部分为View的内容,框就是View本身。
这里大概能将mScrollX和mScrollY的取值表述清楚了。
下面用一个Demo演示一下ScrollTo和ScrollBy的区别:
Activity:
package com.example.xuzhenhao.myapplication.ui;import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;import com.example.xuzhenhao.myapplication.R;public class TestActivity extends AppCompatActivity {private RelativeLayout rl;private TextView tvTo;private TextView tvBy;private int x = -5;private int y = -5;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);initView();}/*** 初始化控件*/private void initView() {rl = (RelativeLayout) findViewById(R.id.scroll_rl);tvTo = (TextView) findViewById(R.id.scroll_tv);tvTo.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {int action = event.getAction();switch (action){case MotionEvent.ACTION_DOWN:rl.scrollTo(x,y);break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:break;}return false;}});tvBy = (TextView) findViewById(R.id.scroll_by_tv);tvBy.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {int action = event.getAction();switch (action){case MotionEvent.ACTION_DOWN:rl.scrollBy(x,y);break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:break;}return false;}});}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/scroll_rl"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.example.xuzhenhao.myapplication.ui.TestActivity"><TextViewandroid:id="@+id/scroll_to_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/dark"android:textSize="16sp"android:text="ScrollTo"/><TextViewandroid:id="@+id/scroll_by_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/scroll_to_tv"android:textColor="@color/dark"android:textSize="16sp"android:text="ScrollBy"/></RelativeLayout>
运行起来如下图所示:
我们发现ScrollTo只能移动一次,再次点击就不能移动了,而点击ScrollBy每次都能移动,玄机在哪里??刚刚放出的源码里面已经写的很清楚了。
ScrollTo第一次传参时将传入的形参分别赋值给mScrollX和mScrollY,而每次都会去判断mScrollX和mScrollY与传入的形参是否相等,如果相等就不会去移动。
ScrollBy方法内部调用ScrollTo,在调用ScrollTo时传入的参数为当前View内容的左边缘和顶部到View的左边缘和顶部的距离加上传入的形参,就相当于每次都实现了基于当前位置的相对滑动
注意:
ScroolTo和ScrollBy都只能移动View的内容,View本身是不会移动的,上图中两个View之所以跑了是因为我们是使用最外层布局RelativeLayout的ScrollTo和ScrollBy
感谢!
在此任玉刚的《Android开发艺术探索》第3章第二节View的滑动
这篇关于View的滑动之ScrollTo和ScrollBy的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!