Android中的ScrollTo和ScrollBy解析


 

 

    關於Android中的ScrollBy和ScrollTo方法相信大家並不陌生,這兩個方法是在View中實現的。所以在各個繼承了View的類都可以使用改方法。

在View中對這兩個方法的源碼編寫是這樣的,有興趣的朋友可以研究一下:

/**

 

/**
* 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);
}

 

 

首先我們來看看To方法,它有一個這樣的判斷
if (mScrollX != x || mScrollY != y)
這是什么意思呢,這里出現了mScrollX和mScrollY兩個數值,做動畫的朋友肯定對這兩個參數不會陌生。 mScrollX是原點(也就是左上角)到指定View的左上角的X軸距離,mScrollY亦然。
這時這個判斷的意義就明確了,就是用於判斷移動量是否是View當前原點,如果不是,則開始下面的代碼

接下來就是交換保存值,刷新視圖,開始調用onScrollChanged方法移動View位置。

而by方法其實就是在調用To方法,這時也就能看出,To單次移動的,而By可以反復的按照自己所給的值移動

 


在這里特別說一下,我們都知道在Android中,坐標原點是在左上角,往右代表x,往下代表Y ,在eclipse中,在填這兩個參數時若要往下xy移動20,寫法是ScrollBy(-20,-20);
而在Android studio中寫法則是ScrollBy(-+20,-+20);來代表放下分別移動20點,如果直接填寫20,會編譯不通過。修改成-+20則不會出問題,不知道是否是我一個人有這個問題。


接下來測試一下這兩個方法。

 

在布局文件中放入兩個Button,一個是用於By另一個是To,代碼如下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
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.xh.admin.myscrolltest.MainActivity">


<Button
android:id="@+id/scrollBy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="By"
/>

<Button
android:id="@+id/srcollTo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/scrollBy"
android:text="To"
/>


</RelativeLayout>


而在MainActivity中簡單的幾行代碼代碼量很小,直接寫到一個方法里。
package com.xh.admin.myscrolltest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;

import static com.xh.admin.myscrolltest.R.id.scrollBy;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

final RelativeLayout re = (RelativeLayout) findViewById(R.id.activity_main);
Button by = (Button) findViewById(scrollBy);
Button To = (Button) findViewById(R.id.srcollTo);

by.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
re.scrollBy(-+20, -+20);

}
});

To.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
re.scrollTo(-+20,-+20);
}
});
}
}

至於為什么Scroll方法中的值是負數,而不是正數,這有一篇文章寫的很好:http://www.tuicool.com/articles/uM7ruy
,在運行這個小的Test代碼時會發現一個問題,無論點擊那個按鈕,另一個按鈕也會一起移動,就算是添加與Scroll方法無關的控件,也一樣會移動,千萬不要以為這是因為相對布局原因,線性布局中也是一樣的,
這是因為,ScrollBy和 To 的行為是,哪個View調用的它,哪個View的內容就開始整個移動,如果是Button調用的其中某個方法,那么Button的位置不會變,但是Button中的內容會移動,現在我們希望Button移動
那馬我們就指定Button的父容器來調用這兩個方法。

如果想要在某個界面中只希望一部分內容移動,可以嵌套布局方法,指定某一個ViewGroup移動。

最近在slidingmenu和ViewPager中常接觸到這兩個方法,特此記錄,寫的很差,大牛勿噴


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM