實現view的移動通常有三種方式
1.調用view的scrollTo 或scrollBy
2.使用動畫來實現
3.重置view的layoutparam
今天我們重點分析一下scrollTo(x, y) scrollBy(x, y)
- 首先說一下兩個方法的用途
用來實現內部內容(這里需要注意:如果是viewgroup內部嵌套view則內部內容為view,如果當前是textview則內部內容指的是text文字)基于當前位置的滑動?;瑒右?guī)則,如果要實現內部內容從左往右的滑動,x為負值,從上往下y為負值。要想說明為啥是這樣,看一下view的位置坐標和父容器之間的關系便知。

需要注意:
view的四個位置參數都是相對于父?容器的相對坐標;
view的寬高可通過坐標計算 width = right- left height = bottom -top
- scrollTo與scrollBy區(qū)別
一句話總結: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);
}
可以發(fā)現,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