Scorller類官方介紹
This class encapsulates scrolling. You can use scrollers (Scroller or OverScroller) to collect the data you need to produce a scrolling animation—for example, in response to a fling gesture. Scrollers track scroll offsets for you over time, but they don't automatically apply those positions to your view. It's your responsibility to get and apply new coordinates at a rate that will make the scrolling animation look smooth.
-
這個類封裝了滾動。 你可以使用scrollers(可譯為滾動起)(Scroller或OverScroller)收集你需要生成的滾動動畫所需要的數(shù)據(jù),例如響應一個甩動手勢。 Scrollers隨著時間的推移跟蹤滾動的偏移量,但不會自動將這些位置設置給你的view。 你有責任按一定的頻率去獲取當前滾動的坐標并應用在你的view上以使?jié)L動動畫看起來很順滑。
示例代碼:private Scroller mScroller = new Scroller(context);
...
public void zoomIn() {
// Revert any animation currently in progress
mScroller.forceFinished(true);
// Start scrolling by providing a starting point and
// the distance to travel
mScroller.startScroll(0, 0, 100, 0);
// Invalidate to request a redraw
invalidate();
} To track the changing positions of the x/y coordinates, use computeScrollOffset(). The method returns a boolean to indicate whether the scroller is finished. If it isn't, it means that a fling or programmatic pan operation is still in progress. You can use this method to find the current offsets of the x and y coordinates, for example:
-
要跟蹤x / y坐標的變化位置,請使用computeScrollOffset()。 該方法返回一個布爾值以指示滾動程序是否完成。 如果還沒有完成,這意味著一個甩動操作或程序化的平移操作仍在進行中。 你可以使用此方法獲得x和y坐標的當前偏移量,例如:
if (mScroller.computeScrollOffset()) { // Get current x and y positions int currX = mScroller.getCurrX(); int currY = mScroller.getCurrY(); ... }
概要說明
- Scroller提供了三個構造函數(shù)
- Scroller(Context context)
Create a Scroller with the default duration and interpolator.
使用默認的持續(xù)時間值和插值器創(chuàng)建一個Scroller- Scroller(Context context, Interpolator interpolator)
Create a Scroller with the specified interpolator.
使用指定的插值器創(chuàng)建一個Scroller,持續(xù)時間之還是默認的250- Scroller(Context context, Interpolator interpolator, boolean flywheel)
Create a Scroller with the specified interpolator.
摘錄自:http://blog.csdn.net/vipzjyno1/article/details/24592591動畫效果:
- AccelerateDecelerateInterpolator: 開始和結束都是緩慢的,通過中間時候加速
- AccelerateInterpolator:先緩慢,后加速
- AnticipateInterpolator:先后退,后前進
- AnticipateOvershootInterpolator:開始后退,然后前進并超過終點位置,最終退回到終點
- BounceInterpolator:彈性衰減到結束
- CycleInterpolator:重復循環(huán)動畫,速度變化遵循正弦定律
- DecelerateInterpolator:先加速,后減速
- LinearInterpolator:線性的
- OvershootInterpolator:超過終點然回來
scroller method
- void abortAnimation()
滾到最終的x,y位置中止動畫。- boolean computeScrollOffset()
調(diào)用該方法計算,獲取當前的位置。
void extendDuration(int extends)
擴展?jié)L動動畫。
void fling(int startX,int startY,int velocityX,int velocityY,int minX,int maxX,int minY,int maxY)
開始滾動基于一個拖拽手勢。
final void forceFinished(boolean finished)
強行停止?jié)L動。
float getCurrVelocity()
返回當前滾動速度。
final int getCurrX()
返回滾動中當前的X偏移量。
final int getCurrY()
返回滾動中當前的Y偏移量。
final int getDuration()
返回滾動事件將花費多長時間,以毫秒為單位。
final int getFinalX()
返回滾動結束的x坐標值。
最終int getFinalY()
返回滾動結束的y坐標值。
final int getStartX()
返回滾動中的起始X偏移量。
final int getStartY()
返回滾動中的起始Y偏移量。
final boolean isFinished()
返回滾動滾輪是否完成滾動。
void setFinalX(int newX)
設置此滾動條的最終位置(X)。
void setFinalY(int newY)
設置此滾動條的最終位置(Y)。
final setFriction(float friction)
設置摩擦力的摩擦量。
void startScroll(int startX,int startY,int dx,int dy,int duration)
通過提供起點,行程距離和滾動持續(xù)時間來開始滾動。
void startScroll(int startX,int startY,int dx,int dy)
通過提供起點和行駛距離開始滾動。
int timePassed()
返回自滾動開始以來經(jīng)過的時間。
引言
- 在自定義View中需要制作滾動效果的時候我們會經(jīng)常遇到這個類,當然也可以通過屬性動畫或者補間動畫實現(xiàn),但是使用scroller實現(xiàn)有個好處,你可以中途取消滾動效果。
Scroller
- 官方文檔也說了,Scroller負責收集滾動所需的數(shù)據(jù),也就是說,Scroller本身并不負責“滾動”這個操作,滾動的操作是有View的scrollTo(x,y) 和scollerBy(dx,dy)這兩個方法完成的。而使用Scroller實現(xiàn)滾動時,比如我們想讓view向下滾動,此時我是一臉懵逼的,要怎么觸發(fā)呢?其實Scroller需要容器類配合實現(xiàn)這個滾動過程,比如一個viewgroup中的childview1 想滾動,觸發(fā)該滾動的并不事childview1自己,而是viewgroup觸發(fā)的。如果你在TextView中使用Scroller,那么滾動時移動的其實是TextView的可視區(qū)域,TextView本身并未移動。
這個理解起來可能比較變扭,我們來借助圖形理解一下:

如上圖:view1從右邊往左下滾動,其實內(nèi)部是將viewgroup的可視區(qū)域往右移動了,
使用Scroller時,最長用的方法就是scrollTo 和ScrollBy,有關這兩個方法的使用介紹和區(qū)別,網(wǎng)上其實有很多相關的文章。
- ScrollTo(int x, int y) 我只要見過,不管你過程如何 ----滑動到(x,y)這個點,不管你怎么跑,你最后得給我滾到這個點就對了。
- 接下來我們來個一簡單的demo實踐一下:先看效果圖

-
代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context="guanaj.com.scrollerdemo.MainActivity"> <LinearLayout android:id="@+id/ll_content" android:layout_width="match_parent" android:background="@android:color/holo_green_light" android:layout_height="wrap_content"> <TextView android:layout_marginTop="6dp" android:layout_marginBottom="6dp" android:background="@android:color/holo_red_dark" android:text="我滾" android:gravity="center" android:id="@+id/txt" android:layout_width="50dp" android:layout_height="50dp" /> </LinearLayout> <Button android:layout_marginTop="20dp" android:id="@+id/start_scrollby" android:text="scrollBy" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/start_scrollto" android:text="scrollTO" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 本次是讓textView進行滾動
-
看實現(xiàn)代碼
package guanaj.com.scrollerdemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Scroller; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private Scroller scroller; private LinearLayout llContent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button startScrollby = (Button) findViewById(R.id.start_scrollby); Button startScrollto = (Button) findViewById(R.id.start_scrollto); llContent = (LinearLayout) findViewById(R.id.ll_content); TextView txt = (TextView) findViewById(R.id.txt); //初始化Scroller scroller = new Scroller(this); startScrollby.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startScrollby(); } }); startScrollto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startScrollto(); } }); } private void startScrollby() { llContent.scrollBy(-100,0); } private void startScrollto() { llContent.scrollTo(0,0); } }
- 當點擊startScrollby的時,讓LinearLayout里面的textview向右滾動100px,這里為什么是-100呢,按照坐標軸來說100才是向右移動才對啊!
- 當時我也是一臉懵逼的,突然一想,不對,移動的并不是textview,而是linearlayout的可視區(qū)域,視覺上的textview向右滾,其實是linearlayout的可視區(qū)域向左移動,所以是-100;當點擊startScrollto的時候,我們讓linearlayout的可視區(qū)域回到原點。
- 由于上傳文件大小限制,效果圖的速度是被加快了的,其實滑動是一下子就滾到一個點的,沒有動畫效果。這種體驗是及不好的。接下來我們就來實現(xiàn)平滑的滾動,讓他瀟灑滾一回吧!
平滑的滾吧!蛋炒飯~~
突然想另起一章來繼續(xù)解析scroller,不要打我,請看下一章節(jié)