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)借助圖形理解一下:
如上圖: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í)踐一下:先看效果圖
-
代碼如下:
<?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é)