先说结论,结论来自《Android开发艺术探索》
- ScrollBy实际上也是调用了ScrollTo方法,它实现了基于当前位置的相对滑动,而ScrollTo实现了基于所传递参数的绝对滑动。
- 所谓的移动是当前控件,里面内容View的移动,比如一个LinearLayout里面包含了一个Button,应该调用LinearLayout的ScrollBy或者ScrollTo方法。
- 从左向右滑动,那么mScrollX为负值,反之为正值;如果从上往下滑动,那么mScrollY为负值,反之为正值。
为了加深印象,我写了个列子
例子
第二个是ScrollTo,因为每次传递的参数,都是从起点开始运动,所以Button始终是在中心打转。
两个自定义布局文件
ScrollBy
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class ScrollByLinearLayout extends LinearLayout {
private final String TAG = getClass().getName();
private int mLastX = 0;
private int mLastY = 0;
public ScrollByLinearLayout(Context context) {
super(context);
}
public ScrollByLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollByLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int dx = x - mLastX;
int dy = y - mLastY;
Log.e(TAG, "ScrollX = " + getScrollX() + " ScrollY = " + getScrollY());
scrollBy(-dx, -dy);
break;
case MotionEvent.ACTION_UP:
break;
}
mLastX = x;
mLastY = y;
return true;
}
}
ScrollTo
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class ScrollToLinearLayout extends LinearLayout {
private final String TAG = getClass().getName();
private int mLastX = 0;
private int mLastY = 0;
public ScrollToLinearLayout(Context context) {
super(context);
}
public ScrollToLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollToLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int dx = x - mLastX;
int dy = y - mLastY;
Log.e(TAG, "ScrollX = " + getScrollX() + " ScrollY = " + getScrollY());
scrollTo(dx, dy);
break;
case MotionEvent.ACTION_UP:
break;
}
mLastX = x;
mLastY = y;
return true;
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<com.hotwheels.myapplication.ScrollByLinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:layout_width="100dp"
android:layout_height="100dp" />
</com.hotwheels.myapplication.ScrollByLinearLayout>
<com.hotwheels.myapplication.ScrollToLinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:layout_width="100dp"
android:layout_height="100dp" />
</com.hotwheels.myapplication.ScrollToLinearLayout>
</LinearLayout>