一、結(jié)構(gòu)
public class Scroller extends Object
創(chuàng)新互聯(lián)建站是專業(yè)的南雄網(wǎng)站建設(shè)公司,南雄接單;提供成都網(wǎng)站建設(shè)、做網(wǎng)站,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行南雄網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
二、概述
這個(gè)類封裝了滾動(dòng)操作。滾動(dòng)的持續(xù)時(shí)間可以通過構(gòu)造函數(shù)傳遞,并且可以指定滾動(dòng)動(dòng)作的持續(xù)的最長(zhǎng)時(shí)間。經(jīng)過這段時(shí)間,滾動(dòng)會(huì)自動(dòng)定位到最終位置,并且通過computeScrollOffset()會(huì)得到的返回值為false,表明滾動(dòng)動(dòng)作已經(jīng)結(jié)束。
三、構(gòu)造函數(shù)
public Scroller (Context context)
使用缺省的持續(xù)持續(xù)時(shí)間和動(dòng)畫插入器創(chuàng)建一個(gè)Scroller。(譯者注:interpolator這里翻譯為動(dòng)畫插入器,見這里。)
public Scroller (Context context, Interpolator interpolator)
根據(jù)指定的動(dòng)畫插入器創(chuàng)建一個(gè)Scroller,如果指定的動(dòng)畫插入器為空,則會(huì)使用缺省的動(dòng)畫插入器(粘滯viscous)創(chuàng)建。
四、公共方法
public void abortAnimation ()
停止動(dòng)畫。與forceFinished(boolean)相反,Scroller滾動(dòng)到最終x與y位置時(shí)中止動(dòng)畫。
參見
forceFinished(boolean)
public boolean computeScrollOffset ()
當(dāng)想要知道新的位置時(shí),調(diào)用此函數(shù)。如果返回true,表示動(dòng)畫還沒有結(jié)束。位置改變以提供一個(gè)新的位置。
public void extendDuration (int extend)
延長(zhǎng)滾動(dòng)動(dòng)畫時(shí)間。此函數(shù)允許當(dāng)使用setFinalX(int) or setFinalY(int) 時(shí),卷動(dòng)動(dòng)作持續(xù)更長(zhǎng)時(shí)間并且卷動(dòng)更長(zhǎng)距離。
參數(shù)
extend 卷動(dòng)事件延長(zhǎng)的時(shí)間,以毫秒為單位
參見
setFinalX(int)
setFinalY(int)
public void fling (int startX, int startY, int velocityX, int velocityY, intminX, int maxX, int minY, int maxY)
在fling(譯者注:快滑,用戶按下觸摸屏、快速移動(dòng)后松開)手勢(shì)基礎(chǔ)上開始滾動(dòng)。滾動(dòng)的距離取決于fling的初速度。
參數(shù)
startX 滾動(dòng)起始點(diǎn)X坐標(biāo)
startY 滾動(dòng)起始點(diǎn)Y坐標(biāo)
velocityX 當(dāng)滑動(dòng)屏幕時(shí)X方向初速度,以每秒像素?cái)?shù)計(jì)算
velocityY 當(dāng)滑動(dòng)屏幕時(shí)Y方向初速度,以每秒像素?cái)?shù)計(jì)算
minX X方向的最小值,scroller不會(huì)滾過此點(diǎn)。
maxX X方向的最大值,scroller不會(huì)滾過此點(diǎn)。
minY Y方向的最小值,scroller不會(huì)滾過此點(diǎn)。
maxY Y方向的最大值,scroller不會(huì)滾過此點(diǎn)。
public final void forceFinished (boolean finished)
強(qiáng)制終止的字段到特定值。(譯者注:立即停止?jié)L動(dòng)?)
參數(shù)
finished 新的結(jié)束值
public final int getCurrX ()
返回當(dāng)前滾動(dòng)X方向的偏移
返回值
距離原點(diǎn)X方向的絕對(duì)值
public final int getCurrY ()
返回當(dāng)前滾動(dòng)Y方向的偏移
返回值
距離原點(diǎn)Y方向的絕對(duì)值
public final int getDuration ()
返回滾動(dòng)事件的持續(xù)時(shí)間,以毫秒計(jì)算。
返回值
滾動(dòng)持續(xù)的毫秒數(shù)
public final int getFinalX ()
返回滾動(dòng)結(jié)束位置。僅針對(duì)“fling”手勢(shì)有效
返回值
最終位置X方向距離原點(diǎn)的絕對(duì)距離
public final int getFinalY ()
返回滾動(dòng)結(jié)束位置。僅針對(duì)“fling”操作有效
返回值
最終位置Y方向距離原點(diǎn)的絕對(duì)距離
public final int getStartX ()
返回滾動(dòng)起始點(diǎn)的X方向的偏移
返回值
起始點(diǎn)在X方向距離原點(diǎn)的絕對(duì)距離
public final int getStartY ()
返回滾動(dòng)起始點(diǎn)的Y方向的偏移
返回值
起始點(diǎn)在Y方向距離原點(diǎn)的絕對(duì)距離
public final boolean isFinished ()
返回scroller是否已完成滾動(dòng)。
返回值
停止?jié)L動(dòng)返回true,否則返回false
public void setFinalX (int newX)
設(shè)置scroller的X方向終止位置
參數(shù)
newX 新位置在X方向距離原點(diǎn)的絕對(duì)偏移。
參見
extendDuration(int)
setFinalY(int)
public void setFinalY (int newY)
設(shè)置scroller的Y方向終止位置
參數(shù)
newY 新位置在Y方向距離原點(diǎn)的絕對(duì)偏移。
參見
extendDuration(int)
setFinalY(int)
public void startScroll (int startX, int startY, int dx, int dy)
以提供的起始點(diǎn)和將要滑動(dòng)的距離開始滾動(dòng)。滾動(dòng)會(huì)使用缺省值250ms作為持續(xù)時(shí)間。
參數(shù)
startX 水平方向滾動(dòng)的偏移值,以像素為單位。正值表明滾動(dòng)將向左滾動(dòng)
startY 垂直方向滾動(dòng)的偏移值,以像素為單位。正值表明滾動(dòng)將向上滾動(dòng)
dx 水平方向滑動(dòng)的距離,正值會(huì)使?jié)L動(dòng)向左滾動(dòng)
dy 垂直方向滑動(dòng)的距離,正值會(huì)使?jié)L動(dòng)向上滾動(dòng)
public void startScroll (int startX, int startY, int dx, int dy, int duration)
以提供的起始點(diǎn)和將要滑動(dòng)的距離開始滾動(dòng)。
參數(shù)
startX 水平方向滾動(dòng)的偏移值,以像素為單位。正值表明滾動(dòng)將向左滾動(dòng)
startY 垂直方向滾動(dòng)的偏移值,以像素為單位。正值表明滾動(dòng)將向上滾動(dòng)
dx 水平方向滑動(dòng)的距離,正值會(huì)使?jié)L動(dòng)向左滾動(dòng)
dy 垂直方向滑動(dòng)的距離,正值會(huì)使?jié)L動(dòng)向上滾動(dòng)
duration 滾動(dòng)持續(xù)時(shí)間,以毫秒計(jì)。
public int timePassed ()
返回自滾動(dòng)開始經(jīng)過的時(shí)間
返回值
經(jīng)過時(shí)間以毫秒為單位
五、簡(jiǎn)單用法:
Android里Scroller類是為了實(shí)現(xiàn)View平滑滾動(dòng)的一個(gè)Helper 類。通常在自定義的View時(shí)使用,在View中定義一個(gè)私有成員mScroller = new Scroller(context)。設(shè)置mScroller滾動(dòng)的位置時(shí),并不會(huì)導(dǎo)致View的滾動(dòng),通常是用mScroller記錄/計(jì)算View滾 動(dòng)的位置,再重寫View的computeScroll(),完成實(shí)際的滾動(dòng)。
自定義一個(gè)CustomView,使用Scroller實(shí)現(xiàn)滾動(dòng)
import android.content.Context;
importandroid.util.AttributeSet;
import android.util.Log;
import android.view.View;
importandroid.widget.LinearLayout;
import android.widget.Scroller;
public class CustomView extendsLinearLayout {
privatestatic final String TAG = "Scroller";
privateScroller mScroller;
publicCustomView(Context context, AttributeSet attrs) {
super(context,attrs);
mScroller= new Scroller(context);
}
//調(diào)用此方法滾動(dòng)到目標(biāo)位置
publicvoid smoothScrollTo(int fx, int fy) {
intdx = fx - mScroller.getFinalX();
intdy = fy - mScroller.getFinalY();
smoothScrollBy(dx,dy);
}
//調(diào)用此方法設(shè)置滾動(dòng)的相對(duì)偏移
publicvoid smoothScrollBy(int dx, int dy) {
//設(shè)置mScroller的滾動(dòng)偏移量
mScroller.startScroll(mScroller.getFinalX(),mScroller.getFinalY(), dx, dy);
invalidate();//這里必須調(diào)用invalidate()才能保證computeScroll()會(huì)被調(diào)用,否則不一定會(huì)刷新界面,看不到滾動(dòng)效果
}
@Override
publicvoid computeScroll() {
//先判斷mScroller滾動(dòng)是否完成
if(mScroller.computeScrollOffset()) {
//這里調(diào)用View的scrollTo()完成實(shí)際的滾動(dòng)
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
//必須調(diào)用該方法,否則不一定能看到滾動(dòng)效果
postInvalidate();
}
super.computeScroll();
}
}
六、深度用法:
android使用Scroller實(shí)現(xiàn)緩慢移動(dòng)
在Launcher中的Workspace中實(shí)現(xiàn)了左右屏幕切換效果,里面就用到了Scroller記錄滑動(dòng)軌跡,實(shí)現(xiàn)一種緩慢地向左或向右移動(dòng)的效果,這里我對(duì)這種效果進(jìn)行總結(jié):
我們先看一個(gè)例子:點(diǎn)擊按鈕時(shí)紅經(jīng)塊會(huì)從左邊緩慢地移向左右,這個(gè)該怎么實(shí)現(xiàn)呢
我們先來看一下,Scroller,這個(gè)對(duì)象里有startScroll方法
void android.widget.Scroller.startScroll(int startX, int startY, int dx, int dy, int duration)
第一個(gè)參數(shù)是起始移動(dòng)的x坐標(biāo)值,第二個(gè)是起始移動(dòng)的y坐標(biāo)值,第三個(gè)第四個(gè)參數(shù)都是移到某點(diǎn)的坐標(biāo)值,而duration當(dāng)然就是執(zhí)行移動(dòng)的時(shí)間。這個(gè)有什么用呢。要知道有什么用還得再看一個(gè)方法
boolean android.widget.Scroller.computeScrollOffset()
當(dāng)startScroll執(zhí)行過程中即在duration時(shí)間內(nèi),computeScrollOffset 方法會(huì)一直返回false,但當(dāng)動(dòng)畫執(zhí)行完成后會(huì)返回返加true.
有了這兩個(gè)方法還不夠,我們還需要再重寫viewGroup的一個(gè)方法,
computeScroll 這個(gè)方法什么時(shí)候會(huì)被調(diào)用呢
官網(wǎng)上這樣說的
[size=0.9em] public void computeScroll [size=0.9em]()[size=0.8em]Since: API Level 1
Called by a parent to request that a child update its values for mScrollX and mScrollY if necessary. This will typically be done if the child is animating a scroll using a Scroller object.
當(dāng)我們執(zhí)行ontouch或invalidate()或postInvalidate()都會(huì)導(dǎo)致這個(gè)方法的執(zhí)行 所以我們像下面這樣調(diào)用,postInvalidate執(zhí)行后,會(huì)去調(diào)computeScroll 方法,而這個(gè)方法里再去調(diào)postInvalidate,這樣就可以不斷地去調(diào)用scrollTo方法了,直到mScroller動(dòng)畫結(jié)束,當(dāng)然第一次時(shí),我們需要手動(dòng)去調(diào)用一次postInvalidate才會(huì)去調(diào)用
computeScroll 方法
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), 0);
postInvalidate();
}
}
七、源碼:
下面附上上面那個(gè)例子的源代碼首先是MyViewGroup.javapackage com.wb;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;
public class MyViewGroup extends LinearLayout {
private boolean s1=true;
Scroller mScroller=null;
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller=new Scroller(context);
// TODO Auto-generated constructor stub
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), 0);
postInvalidate();
}
}
public void beginScroll(){
if (!s1) {
mScroller.startScroll(0, 0, 0, 0, 1000);
s1 = true;
} else {
mScroller.startScroll(0, 0, -500, 0, 1000);
s1 = false;
}
invalidate();
}
}
然后是WheelActivity.java
package com.wb;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.LayoutParams;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Adapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class WheelActivity extends Activity {
private ListView listView = null;
private MyViewGroup myViewGroup;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myViewGroup = (MyViewGroup) findViewById(R.id.myviewGroup);
}
public void scroll(View view) {
myViewGroup.beginScroll();
}
}
main.xml
android:layout_height="fill_parent"
android:orientation="vertical" >
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="scroll"
android:onClick="scroll" />
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" android:id="@+id/myviewGroup">
android:layout_height="fill_parent"
android:background="#ff0000"
android:text="我在這"/>