1. 程式人生 > >ScrollView實現阻尼回彈效果!

ScrollView實現阻尼回彈效果!

今天跟大夥簡紹個ScrollView的阻尼回彈!下拉到一定程度,可以回撥進行重新整理和進行操作等!
直接上程式碼了!

package com.***.fb**.widget;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import
android.widget.ScrollView; /** * @類名:BounceScrollView * @類描述:支援上下反彈效果的ScrollView * @作者:Administrator */ public class BounceScrollView extends ScrollView { private boolean isCalled; private Callback mCallback; /** 包含的View */ private View mView; /** 儲存正常時的位置 */ private Rect mRect = new
Rect(); /** y座標 */ private int y; private boolean isFirst = true; public BounceScrollView(Context context, AttributeSet attrs) { super(context, attrs); } /** * @重寫方法名:onFinishInflate * @父類:@see android.view.View#onFinishInflate() * @方法說明:根據 XML 生成檢視工作完成.該函式在生成檢視的最後呼叫,在所有子檢視新增完之後. 即使子類覆蓋了 onFinishInflate * 方法,也應該呼叫父類的方法,使該方法得以執行. */
@Override protected void onFinishInflate() { if (getChildCount() > 0) mView = getChildAt(0); super.onFinishInflate(); } @Override public boolean onTouchEvent(MotionEvent ev) { if (mView != null) { commonOnTouch(ev); } return super.onTouchEvent(ev); } private void commonOnTouch(MotionEvent ev) { int action = ev.getAction(); int cy = (int) ev.getY(); switch (action) { case MotionEvent.ACTION_DOWN: break; /** 跟隨手指移動 */ case MotionEvent.ACTION_MOVE: int dy = cy - y; if (isFirst) { dy = 0; isFirst = false; } y = cy; if (isNeedMove()) { if (mRect.isEmpty()) { /** 記錄移動前的位置 */ mRect.set(mView.getLeft(), mView.getTop(), mView.getRight(), mView.getBottom()); } mView.layout(mView.getLeft(), mView.getTop() + 2 * dy / 3, mView.getRight(), mView.getBottom() + 2 * dy / 3); if (shouldCallBack(dy)) { if (mCallback != null) { if (!isCalled) { isCalled = true; resetPosition(); mCallback.callback(); } } } } break; /** 反彈回去 */ case MotionEvent.ACTION_UP: if (!mRect.isEmpty()) { resetPosition(); } break; } } /** * @方法說明:當從上往下,移動距離達到一半時,回撥介面 * @方法名稱:shouldCallBack * @param dy * @return * @返回值:boolean */ private boolean shouldCallBack(int dy) { if (dy > 0 && mView.getTop() > getHeight() / 2) return true; return false; } /** * @方法說明:重置座標 * @方法名稱:resetPosition * @返回值:void */ private void resetPosition() { Animation animation = new TranslateAnimation(0, 0, mView.getTop(), mRect.top); animation.setDuration(200); animation.setFillAfter(true); mView.startAnimation(animation); mView.layout(mRect.left, mRect.top, mRect.right, mRect.bottom); mRect.setEmpty(); isFirst = true; isCalled = false; } /** * @方法說明:是否需要移動佈局 inner.getMeasuredHeight():獲取的是控制元件的總高度 * @方法名稱:isNeedMove * @return,getHeight():獲取的是螢幕的高度 * @返回值:boolean */ public boolean isNeedMove() { int offset = mView.getMeasuredHeight() - getHeight(); int scrollY = getScrollY(); // 0是頂部,後面那個是底部 if (scrollY == 0 || scrollY == offset) { return true; } return false; } /** * @方法說明:當scrollView下拉到一定程度後,進行的回撥方法 * @方法名稱:setCallBack * @param callback * @返回值:void */ public void setCallBack(Callback callback) { mCallback = callback; } public interface Callback { void callback(); } }

在xml檔案中

<com.**.***.wid**.BounceScrollView
        android:id="@+id/id_scrollView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/basecolor"
        android:cacheColorHint="@android:color/transparent"
        android:fadingEdge="none"
        android:fillViewport="false"
        android:scrollbars="none" >
        ......
</com.**.***.wid**.BounceScrollView>

在java檔案中

        id_scrollView
                .setVerticalScrollBarEnabled(false);
        id_scrollView
                .setHorizontalScrollBarEnabled(false);
        id_scrollView.setCallBack(new Callback() {
            @Override
            public void callback() {
                //這裡進行操作,如重新整理等
                Tools.showPrompt("重新整理成功!", Tools.TOAST_SHOW);
            }
        });

用了很長時間,效能自我感覺不錯!特意儲存!