实现view的移动通常有三种方式
1.调用view的scrollTo 或scrollBy
2.使用动画来实现
3.重置view的layoutparam
今天我们重点分析一下scrollTo(x, y) scrollBy(x, y)
- 首先说一下两个方法的用途
用来实现内部内容(这里需要注意:如果是viewgroup内部嵌套view则内部内容为view,如果当前是textview则内部内容指的是text文字)基于当前位置的滑动。滑动规则,如果要实现内部内容从左往右的滑动,x为负值,从上往下y为负值。要想说明为啥是这样,看一下view的位置坐标和父容器之间的关系便知。
需要注意:
view的四个位置参数都是相对于父�容器的相对坐标;
view的宽高可通过坐标计算 width = right- left height = bottom -top
- scrollTo与scrollBy区别
一句话总结:scrollTo是基于view初始位置的移动,而scrollBy是基于当前位置的移动。
简单看一眼源码
scrollTo
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
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
可以发现,scrollTo中每次纪录了上次移动的位置,且如果移动x、y没有变化时不会进行移动;而scrollBy是在上次移动的基础上进行的移动。
View的scrooll移动只改变了view的mScrollX和ScrollY,这两个参数可以通过view的get方法进行获取。
- demo实现
Activity代码
package sunhailong01.myandroidp;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class Main2Activity extends Activity {
private TextView textView;
private View rl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
textView = findViewById(R.id.textView4);
rl = findViewById(R.id.rl);
textView.getX();
textView.getY();
textView.getTranslationX();
textView.getTranslationY();
Log.d("shl", "tvgetX" + textView.getX());
Log.d("shl", "tvgetY" + textView.getY());
Log.d("shl", "tvgetTranslationX" + textView.getTranslationX());
Log.d("shl", "tvgetTranslationY" + textView.getTranslationY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "rlgetX" + rl.getX());
Log.d("shl", "rlgetY" + rl.getY());
Log.d("shl", "rlgetTranslationX" + rl.getTranslationX());
Log.d("shl", "rlgetTranslationY" + rl.getTranslationY());
Log.d("shl", "rl.getScrollX" + rl.getScrollX());
Log.d("shl", "rl.getScrollY" + rl.getScrollY());
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
rl.scrollTo(-30, -20);
Log.d("shl", "scrollTo=======================");
Log.d("shl", "tvgetX" + textView.getX());
Log.d("shl", "tvgetY" + textView.getY());
Log.d("shl", "tvgetTranslationX" + textView.getTranslationX());
Log.d("shl", "tvgetTranslationY" + textView.getTranslationY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "rlgetX" + rl.getX());
Log.d("shl", "rlgetY" + rl.getY());
Log.d("shl", "rlgetTranslationX" + rl.getTranslationX());
Log.d("shl", "rlgetTranslationY" + rl.getTranslationY());
Log.d("shl", "rl.getScrollX" + rl.getScrollX());
Log.d("shl", "rl.getScrollY" + rl.getScrollY());
Log.d("shl", "scrollTo=======================");
}
}, 1000);
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.d("shl", "scrollTo=======================");
rl.scrollTo(-30, -20);
Log.d("shl", "tvgetX" + textView.getX());
Log.d("shl", "tvgetY" + textView.getY());
Log.d("shl", "tvgetTranslationX" + textView.getTranslationX());
Log.d("shl", "tvgetTranslationY" + textView.getTranslationY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "rlgetX" + rl.getX());
Log.d("shl", "rlgetY" + rl.getY());
Log.d("shl", "rlgetTranslationX" + rl.getTranslationX());
Log.d("shl", "rlgetTranslationY" + rl.getTranslationY());
Log.d("shl", "rl.getScrollX" + rl.getScrollX());
Log.d("shl", "rl.getScrollY" + rl.getScrollY());
Log.d("shl", "scrollTo=======================");
}
}, 2000);
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.d("shl", "scrollBy=======================");
rl.scrollBy(-30, -20);
Log.d("shl", "tvgetX" + textView.getX());
Log.d("shl", "tvgetY" + textView.getY());
Log.d("shl", "tvgetTranslationX" + textView.getTranslationX());
Log.d("shl", "tvgetTranslationY" + textView.getTranslationY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "tvgetScrollY" + textView.getScrollY());
Log.d("shl", "rlgetX" + rl.getX());
Log.d("shl", "rlgetY" + rl.getY());
Log.d("shl", "rlgetTranslationX" + rl.getTranslationX());
Log.d("shl", "rlgetTranslationY" + rl.getTranslationY());
Log.d("shl", "rl.getScrollX" + rl.getScrollX());
Log.d("shl", "rl.getScrollY" + rl.getScrollY());
Log.d("shl", "scrollBy=======================");
}
}, 2500);
}
}
xml
<?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"
tools:context=".Main2Activity">
<RelativeLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:id="@+id/rl"
android:background="#333333">
<TextView
android:id="@+id/textView4"
android:layout_width="140dp"
android:layout_height="140dp"
android:text="TextView"
android:textColor="#333"
android:background="#3385ff"
/>
</RelativeLayout>
</LinearLayout>
log打印情况
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: scrollTo=======================
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: tvgetX0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: tvgetY0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: tvgetTranslationX0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: tvgetTranslationY0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: tvgetScrollY0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: tvgetScrollY0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: rlgetX0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: rlgetY0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: rlgetTranslationX0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: rlgetTranslationY0.0
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: rl.getScrollX-30
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: rl.getScrollY-20
12-13 15:20:40.262 29699-29699/sunhailong01.myandroidp D/shl: scrollTo=======================
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: scrollBy=======================
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: tvgetX0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: tvgetY0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: tvgetTranslationX0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: tvgetTranslationY0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: tvgetScrollY0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: tvgetScrollY0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: rlgetX0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: rlgetY0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: rlgetTranslationX0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: rlgetTranslationY0.0
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: rl.getScrollX-60
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: rl.getScrollY-40
12-13 15:20:40.762 29699-29699/sunhailong01.myandroidp D/shl: scrollBy=======================
结论:
- 移动的是内容
- 当调用两次scrollTo传参相同情况下,view并没进行移动,当scrollBy传相同参数时,view进行了移动
- view调用scrollTo或者scrollBy不会改变view的x,y,TranslationX,TranslationY