ScrollView實現阻尼回彈效果!
阿新 • • 發佈:2019-01-25
今天跟大夥簡紹個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);
}
});
用了很長時間,效能自我感覺不錯!特意儲存!