Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 從0開始自定義控件之View的彈性滑動(三)

Android 從0開始自定義控件之View的彈性滑動(三)

編輯:關於Android編程

前言

用scrollTo()和scrollBy()方法實現了View的滑動,但是實現的效果非常的生硬,用戶體驗很差。
這一篇繼續在原有基礎上,擴展下View的彈性滑動。下面詳細介紹下實現Viiew彈性滑動的幾種方式。

Scroller

我們可以使用Scroller這個類來實現View內容的彈性滑動,使用起來也很簡單,只需三步:

第一步:創建Scroller對象。
Scroller mScroller = new Scroller(context);
第二步:調用startScroll()方法。
mScroller.startScroll(getScrollX(), getScrollY() , -50, -50);
invalidate();
第三步:重寫View的computeScroll()方法,實現具體滑動邏輯。
@Override
public void computeScroll() {
    if(mScroller.computeScrollOffset()){
        scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
        invalidate();
    }
}

下面以一個簡單的例子演示下Scroller這個類的用法:

首先自定義一個LinearLayout,並在構造中創建了Scroller對象,提供了一個startScroll()方法,並且重寫了computeScroll()方法:

/**
 * 作者:周游
 * 時間:2016/11/13
 * 博客:http://blog.csdn.net/airsaid
 */
public class ScrollerLinearLayout extends LinearLayout{

    private final Scroller mScroller;

    public ScrollerLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mScroller = new Scroller(context);
    }

    public void startScroll(){
        mScroller.startScroll(getScrollX(), getScrollY() , -50, -50);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if(mScroller.computeScrollOffset()){
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }
}

在布局中用該自定義LinearLayout包裹了一個Button:


在代碼中調用了其startScroll()方法:

public class MainActivity extends AppCompatActivity {

    private ScrollerLinearLayout mLayout;

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

        mLayout = (ScrollerLinearLayout) findViewById(R.id.layout);
    }

    public void start(View v){
        mLayout.startScroll();
    }
}

運行結果:
這裡寫圖片描述
通過上面的例子,簡單實現了用Scroller實現了View的彈性滑動。但是這一切都是怎麼一個過程呢?首先來看看Scroller的startScroll()方法:

public void startScroll(int startX, int startY, int dx, int dy, int duration) {
    mMode = SCROLL_MODE;
    mFinished = false;
    mDuration = duration;
    mStartTime = AnimationUtils.currentAnimationTimeMillis();
    mStartX = startX;
    mStartY = startY;
    mFinalX = startX + dx;
    mFinalY = startY + dy;
    mDeltaX = dx;
    mDeltaY = dy;
    mDurationReciprocal = 1.0f / (float) mDuration;
}

通過查看startScroll()方法的源碼可以發現,其內部只是做了賦值的操作,並沒有調用其他的方法,那麼這個彈性滑動的效果又是從哪裡來的呢?

答案就在於,我們在調用startScroll()方法後又調用了invalidate()方法使View進行了重繪。那麼這時就會走View的draw方法,在View的draw方法中又會去調用View的computeScroll()方法,而該方法在View中是一個空實現。這就解釋了我們為什麼需要復寫computeScroll()方法。

在computeScroll()方法中,我們調用了computeScrollOffset()方法進行判斷,該方法內部會根據時間的流逝來計算出scrollX和scrollY改變的百分比並計算出當前的值。這個方法的返回值也很重要,返回true表示滑動還未結束,false表示滑動已經結束。所以在這裡,我們進行了判斷,當其返回true時,就調用scrollTo()方法使View滑動,並調用invalidate()重繪,只要滑動沒有完成就繼續遞歸下去。

到這裡Scroller的工作原理就很清晰了,Scroller並不能單獨完成View的彈性滑動,而是要配合View的computeScroll()方法,不斷的通過invalidate()方法重繪View,計算Scroller的X和Y值,並通過scrollTo()方法一點點的移動,連在一起,就形成了彈性滑動。

動畫

使用動畫使View實現滑動效果,其本身就具有彈性滑動的效果。所以只要掌握了動畫的使用,那麼就可以輕松實現出View的彈性滑動效果。

延時策略

除了上面的幾種實現方式之外,我們還可以使用延時策略。延時策略就是通過發送一系列的延時消息從而達到一種漸進式的效果。我們可以使用Handler的postDelayed方法,也可以使用其他的延遲消息方法。這裡我們就用Handler來實現一個簡單的彈性滑動效果:

rivate int mStartX = 0;
Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what){
            case 0:
                if(mStartX > -100){
                    mLayout.scrollTo(mStartX, 0);
                    mStartX --;
                    mHandler.sendEmptyMessageDelayed(0, 5);
                }
                break;
        }
    }
};

點擊按鈕時,發送延時消息:

mHandler.sendEmptyMessageDelayed(0, 5);

運行結果:
這裡寫圖片描述

總結

通過了解以上幾種實現彈性滑動的方法,知道了可以用Scroller實現View內的彈性滑動,使用動畫可以實現View的彈性滑動。
在這幾種方式中,其實更重要的是實現思想。只要掌握了其思想,那麼就可以靈活運用起來,實現更多復雜的效果。

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved