Scorller的使用詳解一

更多分享:http://www.cherylgood.cn

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.

  • 這個(gè)類封裝了滾動(dòng)鞭衩。 你可以使用scrollers(可譯為滾動(dòng)起)(Scroller或OverScroller)收集你需要生成的滾動(dòng)動(dòng)畫所需要的數(shù)據(jù)腹备,例如響應(yīng)一個(gè)甩動(dòng)手勢(shì)。 Scrollers隨著時(shí)間的推移跟蹤滾動(dòng)的偏移量专控,但不會(huì)自動(dòng)將這些位置設(shè)置給你的view粟按。 你有責(zé)任按一定的頻率去獲取當(dāng)前滾動(dòng)的坐標(biāo)并應(yīng)用在你的view上以使?jié)L動(dòng)動(dòng)畫看起來(lái)很順滑诬滩。
    示例代碼:

    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坐標(biāo)的變化位置霹粥,請(qǐng)使用computeScrollOffset()。 該方法返回一個(gè)布爾值以指示滾動(dòng)程序是否完成疼鸟。 如果還沒(méi)有完成后控,這意味著一個(gè)甩動(dòng)操作或程序化的平移操作仍在進(jìn)行中。 你可以使用此方法獲得x和y坐標(biāo)的當(dāng)前偏移量空镜,例如:

    if (mScroller.computeScrollOffset()) {
     // Get current x and y positions
     int currX = mScroller.getCurrX();
     int currY = mScroller.getCurrY();
    ...
      }
    

概要說(shuō)明


  • Scroller提供了三個(gè)構(gòu)造函數(shù)
  • Scroller(Context context)
    Create a Scroller with the default duration and interpolator.
    使用默認(rèn)的持續(xù)時(shí)間值和插值器創(chuàng)建一個(gè)Scroller
  • Scroller(Context context, Interpolator interpolator)
    Create a Scroller with the specified interpolator.
    使用指定的插值器創(chuàng)建一個(gè)Scroller浩淘,持續(xù)時(shí)間之還是默認(rèn)的250
  • Scroller(Context context, Interpolator interpolator, boolean flywheel)
    Create a Scroller with the specified interpolator.

摘錄自:http://blog.csdn.net/vipzjyno1/article/details/24592591動(dòng)畫效果:

  • AccelerateDecelerateInterpolator: 開(kāi)始和結(jié)束都是緩慢的,通過(guò)中間時(shí)候加速
  • AccelerateInterpolator:先緩慢吴攒,后加速
  • AnticipateInterpolator:先后退张抄,后前進(jìn)
  • AnticipateOvershootInterpolator:開(kāi)始后退禾锤,然后前進(jìn)并超過(guò)終點(diǎn)位置吹菱,最終退回到終點(diǎn)
  • BounceInterpolator:彈性衰減到結(jié)束
  • CycleInterpolator:重復(fù)循環(huán)動(dòng)畫蜈出,速度變化遵循正弦定律
  • DecelerateInterpolator:先加速鸳兽,后減速
  • LinearInterpolator:線性的
  • OvershootInterpolator:超過(guò)終點(diǎn)然回來(lái)

scroller method

  • void abortAnimation()
    滾到最終的x,y位置中止動(dòng)畫优床。
  • boolean computeScrollOffset()
    調(diào)用該方法計(jì)算绷耍,獲取當(dāng)前的位置蛾号。
    void extendDuration(int extends)
    擴(kuò)展?jié)L動(dòng)動(dòng)畫碘赖。
    void fling(int startX矾缓,int startY怀酷,int velocityX,int velocityY嗜闻,int minX蜕依,int maxX,int minY琉雳,int maxY)
    開(kāi)始滾動(dòng)基于一個(gè)拖拽手勢(shì)样眠。
    final void forceFinished(boolean finished)
    強(qiáng)行停止?jié)L動(dòng)。
    float getCurrVelocity()
    返回當(dāng)前滾動(dòng)速度翠肘。
    final int getCurrX()
    返回滾動(dòng)中當(dāng)前的X偏移量檐束。
    final int getCurrY()
    返回滾動(dòng)中當(dāng)前的Y偏移量。
    final int getDuration()
    返回滾動(dòng)事件將花費(fèi)多長(zhǎng)時(shí)間束倍,以毫秒為單位被丧。
    final int getFinalX()
    返回滾動(dòng)結(jié)束的x坐標(biāo)值。
    最終int getFinalY()
    返回滾動(dòng)結(jié)束的y坐標(biāo)值绪妹。
    final int getStartX()
    返回滾動(dòng)中的起始X偏移量甥桂。
    final int getStartY()
    返回滾動(dòng)中的起始Y偏移量。
    final boolean isFinished()
    返回滾動(dòng)滾輪是否完成滾動(dòng)邮旷。
    void setFinalX(int newX)
    設(shè)置此滾動(dòng)條的最終位置(X)黄选。
    void setFinalY(int newY)
    設(shè)置此滾動(dòng)條的最終位置(Y)。
    final setFriction(float friction)
    設(shè)置摩擦力的摩擦量婶肩。
    void startScroll(int startX办陷,int startY貌夕,int dx,int dy民镜,int duration)
    通過(guò)提供起點(diǎn)啡专,行程距離和滾動(dòng)持續(xù)時(shí)間來(lái)開(kāi)始滾動(dòng)。
    void startScroll(int startX制圈,int startY植旧,int dx,int dy)
    通過(guò)提供起點(diǎn)和行駛距離開(kāi)始滾動(dòng)离唐。
    int timePassed()
    返回自滾動(dòng)開(kāi)始以來(lái)經(jīng)過(guò)的時(shí)間。

引言


  • 在自定義View中需要制作滾動(dòng)效果的時(shí)候我們會(huì)經(jīng)常遇到這個(gè)類问窃,當(dāng)然也可以通過(guò)屬性動(dòng)畫或者補(bǔ)間動(dòng)畫實(shí)現(xiàn)亥鬓,但是使用scroller實(shí)現(xiàn)有個(gè)好處,你可以中途取消滾動(dòng)效果域庇。

Scroller


  • 官方文檔也說(shuō)了嵌戈,Scroller負(fù)責(zé)收集滾動(dòng)所需的數(shù)據(jù),也就是說(shuō)听皿,Scroller本身并不負(fù)責(zé)“滾動(dòng)”這個(gè)操作熟呛,滾動(dòng)的操作是有View的scrollTo(x,y) 和scollerBy(dx,dy)這兩個(gè)方法完成的。而使用Scroller實(shí)現(xiàn)滾動(dòng)時(shí)尉姨,比如我們想讓view向下滾動(dòng)庵朝,此時(shí)我是一臉懵逼的,要怎么觸發(fā)呢又厉?其實(shí)Scroller需要容器類配合實(shí)現(xiàn)這個(gè)滾動(dòng)過(guò)程九府,比如一個(gè)viewgroup中的childview1 想滾動(dòng),觸發(fā)該滾動(dòng)的并不事childview1自己覆致,而是viewgroup觸發(fā)的侄旬。如果你在TextView中使用Scroller,那么滾動(dòng)時(shí)移動(dòng)的其實(shí)是TextView的可視區(qū)域煌妈,TextView本身并未移動(dòng)儡羔。
    這個(gè)理解起來(lái)可能比較變扭,我們來(lái)借助圖形理解一下:
111.png

如上圖:view1從右邊往左下滾動(dòng)璧诵,其實(shí)內(nèi)部是將viewgroup的可視區(qū)域往右移動(dòng)了汰蜘,
使用Scroller時(shí),最長(zhǎng)用的方法就是scrollTo 和ScrollBy腮猖,有關(guān)這兩個(gè)方法的使用介紹和區(qū)別鉴扫,網(wǎng)上其實(shí)有很多相關(guān)的文章。

  • ScrollTo(int x, int y) 我只要見(jiàn)過(guò)澈缺,不管你過(guò)程如何 ----滑動(dòng)到(x,y)這個(gè)點(diǎn)坪创,不管你怎么跑炕婶,你最后得給我滾到這個(gè)點(diǎn)就對(duì)了。

  • 接下來(lái)我們來(lái)個(gè)一簡(jiǎn)單的demo實(shí)踐一下:先看效果圖
2017-04-17 17_52_43.gif
  • 代碼如下:

    <?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進(jìn)行滾動(dòng)

  • 看實(shí)現(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);
    
    }
    }
    
  • 當(dāng)點(diǎn)擊startScrollby的時(shí)莱预,讓LinearLayout里面的textview向右滾動(dòng)100px柠掂,這里為什么是-100呢,按照坐標(biāo)軸來(lái)說(shuō)100才是向右移動(dòng)才對(duì)耙谰凇涯贞!
  • 當(dāng)時(shí)我也是一臉懵逼的,突然一想危喉,不對(duì)宋渔,移動(dòng)的并不是textview,而是linearlayout的可視區(qū)域辜限,視覺(jué)上的textview向右滾皇拣,其實(shí)是linearlayout的可視區(qū)域向左移動(dòng),所以是-100薄嫡;當(dāng)點(diǎn)擊startScrollto的時(shí)候氧急,我們讓linearlayout的可視區(qū)域回到原點(diǎn)。
  • 由于上傳文件大小限制毫深,效果圖的速度是被加快了的吩坝,其實(shí)滑動(dòng)是一下子就滾到一個(gè)點(diǎn)的,沒(méi)有動(dòng)畫效果哑蔫。這種體驗(yàn)是及不好的钉寝。接下來(lái)我們就來(lái)實(shí)現(xiàn)平滑的滾動(dòng),讓他瀟灑滾一回吧闸迷!

平滑的滾吧瘩蚪!蛋炒飯~~

突然想另起一章來(lái)繼續(xù)解析scroller,不要打我稿黍,請(qǐng)看下一章節(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疹瘦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子巡球,更是在濱河造成了極大的恐慌言沐,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酣栈,死亡現(xiàn)場(chǎng)離奇詭異险胰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)矿筝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門起便,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事榆综∶畋裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵鼻疮,是天一觀的道長(zhǎng)怯伊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)判沟,這世上最難降的妖魔是什么耿芹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮挪哄,結(jié)果婚禮上吧秕,老公的妹妹穿的比我還像新娘。我一直安慰自己迹炼,他們只是感情好寇甸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著疗涉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吟秩。 梳的紋絲不亂的頭發(fā)上咱扣,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音涵防,去河邊找鬼闹伪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛壮池,可吹牛的內(nèi)容都是我干的偏瓤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼椰憋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厅克!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起橙依,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤证舟,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后窗骑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體女责,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年创译,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抵知。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖刷喜,靈堂內(nèi)的尸體忽然破棺而出残制,到底是詐尸還是另有隱情,我是刑警寧澤吱肌,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布痘拆,位于F島的核電站,受9級(jí)特大地震影響氮墨,放射性物質(zhì)發(fā)生泄漏纺蛆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一规揪、第九天 我趴在偏房一處隱蔽的房頂上張望桥氏。 院中可真熱鬧,春花似錦猛铅、人聲如沸字支。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)堕伪。三九已至,卻和暖如春栗菜,著一層夾襖步出監(jiān)牢的瞬間欠雌,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工疙筹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留富俄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓而咆,卻偏偏與公主長(zhǎng)得像霍比,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子暴备,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,528評(píng)論 25 707
  • 一悠瞬、Android開(kāi)發(fā)初體驗(yàn) 二、Android與MVC設(shè)計(jì)模式模型對(duì)象存儲(chǔ)著應(yīng)用的數(shù)據(jù)和業(yè)務(wù)邏輯涯捻。模型類通常用來(lái)...
    為夢(mèng)想戰(zhàn)斗閱讀 875評(píng)論 0 3
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程阁危,因...
    小菜c閱讀 6,358評(píng)論 0 17
  • ViewDragHelper實(shí)例的創(chuàng)建 ViewDragHelper重載了兩個(gè)create()靜態(tài)方法public...
    傀儡世界閱讀 654評(píng)論 0 3
  • 本已成仙,你卻讓我回到人間汰瘫,塵緣已了狂打,是你讓我再續(xù)前緣,若是輪回混弥,注定我歷經(jīng)磨難趴乡,往生債未了对省,不還也罷,何苦晾捏,何苦...
    愿得一人懂我詩(shī)閱讀 239評(píng)論 0 4