欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義View實現(xiàn)豎向滑動回彈效果

 更新時間:2022年04月18日 15:49:39   作者:DwView  
這篇文章主要為大家詳細介紹了Android自定義View實現(xiàn)滑動回彈效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Android自定義View實現(xiàn)滑動回彈的具體代碼,供大家參考,具體內容如下

前言

Android 頁面滑動的時候的回彈效果

一、關鍵代碼

public class UniversalBounceView extends FrameLayout implements IPull {
?
? ? private static final String TAG = "UniversalBounceView";
? ? //default.
? ? private static final int SCROLL_DURATION = 200;
? ? private static final float SCROLL_FRACTION = 0.4f;
?
? ? private static final int VIEW_TYPE_NORMAL = 0;
? ? private static final int VIEW_TYPE_ABSLISTVIEW = 1;
? ? private static final int VIEW_TYPE_SCROLLVIEW = 2;
?
? ? private static float VIEW_SCROLL_MAX = 720;
? ? private int viewHeight;
?
? ? private AbsListView alv;
? ? private OnBounceStateListener onBounceStateListener;
?
? ? private View child;
? ? private Scroller scroller;
? ? private boolean pullEnabled = true;
? ? private boolean pullPaused;
? ? private int touchSlop = 8;
?
? ? private int mPointerId;
?
? ? private float downY, lastDownY, tmpY;
? ? private int lastPointerIndex;
?
? ? private float moveDiffY;
? ? private boolean isNotJustInClickMode;
? ? private int moveDelta;
? ? private int viewType = VIEW_TYPE_NORMAL;
?
? ? public UniversalBounceView(Context context) {
? ? ? ? super(context);
? ? ? ? init(context);
? ? }
?
? ? public UniversalBounceView(Context context, AttributeSet attrs) {
? ? ? ? super(context, attrs);
? ? ? ? init(context);
? ? }
?
? ? public UniversalBounceView(Context context, AttributeSet attrs, int defStyleAttr) {
? ? ? ? super(context, attrs, defStyleAttr);
? ? ? ? init(context);
? ? }
?
? ? private void init(Context context) {
? ? ? ? scroller = new Scroller(context, new CustomDecInterpolator());
? ? ? ? touchSlop = (int) (ViewConfiguration.get(context).getScaledTouchSlop() * 1.5);
? ? }
?
? ? class CustomDecInterpolator extends DecelerateInterpolator {
?
? ? ? ? public CustomDecInterpolator() {
? ? ? ? ? ? super();
? ? ? ? }
?
? ? ? ? public CustomDecInterpolator(float factor) {
? ? ? ? ? ? super(factor);
? ? ? ? }
?
? ? ? ? public CustomDecInterpolator(Context context, AttributeSet attrs) {
? ? ? ? ? ? super(context, attrs);
? ? ? ? }
?
? ? ? ? @Override
? ? ? ? public float getInterpolation(float input) {
? ? ? ? ? ? return (float) Math.pow(input, 6.0 / 12);
? ? ? ? }
? ? }
?
? ? private void checkCld() {
? ? ? ? int cnt = getChildCount();
? ? ? ? if (1 <= cnt) {
? ? ? ? ? ? child = getChildAt(0);
? ? ? ? } else if (0 == cnt) {
? ? ? ? ? ? pullEnabled = false;
? ? ? ? ? ? child = new View(getContext());
? ? ? ? } else {
? ? ? ? ? ? throw new ArrayIndexOutOfBoundsException("child count can not be less than 0.");
? ? ? ? }
? ? }
?
? ? @Override
? ? protected void onFinishInflate() {
? ? ? ? checkCld();
? ? ? ? super.onFinishInflate();
? ? }
?
? ? @Override
? ? protected void onSizeChanged(int w, int h, int oldw, int oldh) {
? ? ? ? super.onSizeChanged(w, h, oldw, oldh);
? ? ? ? viewHeight = h;
? ? ? ? VIEW_SCROLL_MAX = h * 1 / 3;
? ? }
?
? ? private boolean isTouch = true;
?
? ? public void setTouch(boolean isTouch) {
? ? ? ? this.isTouch = isTouch;
? ? }
?
? ? @Override
? ? public boolean dispatchTouchEvent(MotionEvent ev) {
? ? ? ? if (!isTouch) {
? ? ? ? ? ? return true;
? ? ? ? } else {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? if (isPullEnable()) {
? ? ? ? ? ? ? ? ? ? if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
? ? ? ? ? ? ? ? ? ? ? ? if (Math.abs(ev.getY() - tmpY) < touchSlop) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? return super.dispatchTouchEvent(ev);
? ? ? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? tmpY = Integer.MIN_VALUE;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? return takeEvent(ev);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } catch (IllegalArgumentException | IllegalStateException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? ? ? if (getVisibility() != View.VISIBLE) {
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? return super.dispatchTouchEvent(ev);
? ? ? ? }
? ? }
?
? ? private boolean takeEvent(MotionEvent ev) {
? ? ? ? int action = ev.getActionMasked();
? ? ? ? switch (action) {
? ? ? ? ? ? case MotionEvent.ACTION_DOWN:
? ? ? ? ? ? ? ? mPointerId = ev.getPointerId(0);
? ? ? ? ? ? ? ? downY = ev.getY();
? ? ? ? ? ? ? ? tmpY = downY;
? ? ? ? ? ? ? ? scroller.setFinalY(scroller.getCurrY());
? ? ? ? ? ? ? ? setScrollY(scroller.getCurrY());
? ? ? ? ? ? ? ? scroller.abortAnimation();
? ? ? ? ? ? ? ? pullPaused = true;
? ? ? ? ? ? ? ? isNotJustInClickMode = false;
? ? ? ? ? ? ? ? moveDelta = 0;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_UP:
? ? ? ? ? ? case MotionEvent.ACTION_CANCEL:
? ? ? ? ? ? ? ? pullPaused = false;
? ? ? ? ? ? ? ? smoothScrollTo(0);
? ? ? ? ? ? ? ? if (isNotJustInClickMode) {
? ? ? ? ? ? ? ? ? ? ev.setAction(MotionEvent.ACTION_CANCEL);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? postDelayed(new Runnable() {
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? ? ? if (getScrollY() == 0 && onBounceStateListener != null) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? onBounceStateListener.overBounce();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }, 200);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_MOVE:
? ? ? ? ? ? ? ? lastPointerIndex = ev.findPointerIndex(mPointerId);
? ? ? ? ? ? ? ? lastDownY = ev.getY(lastPointerIndex);
? ? ? ? ? ? ? ? moveDiffY = Math.round((lastDownY - downY) * getScrollFraction());
? ? ? ? ? ? ? ? downY = lastDownY;
? ? ? ? ? ? ? ? boolean canStart = isCanPullStart();
? ? ? ? ? ? ? ? boolean canEnd = isCanPullEnd();
? ? ? ? ? ? ? ? int scroll = getScrollY();
? ? ? ? ? ? ? ? float total = scroll - moveDiffY;
? ? ? ? ? ? ? ? if (canScrollInternal(scroll, canStart, canEnd)) {
? ? ? ? ? ? ? ? ? ? handleInternal();
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if (Math.abs(scroll) > VIEW_SCROLL_MAX) {
? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? if ((canStart && total < 0) || (canEnd && total > 0)) {
? ? ? ? ? ? ? ? ? ? if (moveDelta < touchSlop) {
? ? ? ? ? ? ? ? ? ? ? ? moveDelta += Math.abs(moveDiffY);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? isNotJustInClickMode = true;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (onBounceStateListener != null) {
? ? ? ? ? ? ? ? ? ? ? ? onBounceStateListener.onBounce();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? scrollBy(0, (int) -moveDiffY);
? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? }
// ? ? ? ? ? ? ? ?else if ((total > 0 && canStart) || (total < 0 && canEnd)) {
// ? ? ? ? ? ? ? ? ? ?if (moveDelta < touchSlop) {
// ? ? ? ? ? ? ? ? ? ? ? ?moveDelta += Math.abs(moveDiffY);
// ? ? ? ? ? ? ? ? ? ?} else {
// ? ? ? ? ? ? ? ? ? ? ? ?isNotJustInClickMode = true;
// ? ? ? ? ? ? ? ? ? ?}
// ? ? ? ? ? ? ? ? ? ?scrollBy(0, -scroll);
// ? ? ? ? ? ? ? ? ? ?return true;
// ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_POINTER_UP:
? ? ? ? ? ? ? ? handlePointerUp(ev, 1);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? return super.dispatchTouchEvent(ev);
? ? }
?
? ? private boolean canScrollInternal(int scroll, boolean canStart, boolean canEnd) {
? ? ? ? boolean result = false;
? ? ? ? if ((child instanceof RecyclerView) || (child instanceof AbsListView) || child instanceof ScrollView) {
? ? ? ? ? ? viewType = VIEW_TYPE_ABSLISTVIEW;
? ? ? ? ? ? result = canStart && canEnd;
? ? ? ? } else if (child instanceof ScrollView || child instanceof NestedScrollView) {
? ? ? ? ? ? viewType = VIEW_TYPE_SCROLLVIEW;
? ? ? ? } else {
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? if (result) {
? ? ? ? ? ? isNotJustInClickMode = true;
? ? ? ? ? ? if (moveDelta < touchSlop) {
? ? ? ? ? ? ? ? moveDelta += Math.abs(moveDiffY);
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? if (((scroll == 0 && canStart && moveDiffY < 0) || (scroll == 0 && canEnd && moveDiffY > 0) || (!canStart && !canEnd))) {
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? if (moveDelta < touchSlop) {
? ? ? ? ? ? moveDelta += Math.abs(moveDiffY);
? ? ? ? ? ? return true;
? ? ? ? } else {
? ? ? ? ? ? isNotJustInClickMode = true;
? ? ? ? }
? ? ? ? return false;
? ? }
?
? ? private void handleInternal() {
?
? ? }
?
? ? private void handlePointerUp(MotionEvent event, int type) {
? ? ? ? int pointerIndexLeave = event.getActionIndex();
? ? ? ? int pointerIdLeave = event.getPointerId(pointerIndexLeave);
? ? ? ? if (mPointerId == pointerIdLeave) {
? ? ? ? ? ? int reIndex = pointerIndexLeave == 0 ? 1 : 0;
? ? ? ? ? ? mPointerId = event.getPointerId(reIndex);
? ? ? ? ? ? // 調整觸摸位置,防止出現(xiàn)跳動
? ? ? ? ? ? downY = event.getY(reIndex);
? ? ? ? }
? ? }
?
? ? @Override
? ? public boolean onTouchEvent(MotionEvent event) {
? ? ? ? return super.onTouchEvent(event);
? ? }
?
? ? private void smoothScrollTo(int value) {
? ? ? ? int scroll = getScrollY();
? ? ? ? scroller.startScroll(0, scroll, 0, value - scroll, SCROLL_DURATION);
? ? ? ? postInvalidate();
? ? }
?
? ? @Override
? ? public void computeScroll() {
? ? ? ? super.computeScroll();
? ? ? ? if (!pullPaused && scroller.computeScrollOffset()) {
? ? ? ? ? ? scrollTo(scroller.getCurrX(), scroller.getCurrY());
? ? ? ? ? ? postInvalidate();
? ? ? ? }
? ? }
?
? ? private float getScrollFraction() {
? ? ? ? float ratio = Math.abs(getScrollY()) / VIEW_SCROLL_MAX;
? ? ? ? ratio = ratio < 1 ? ratio : 1;
? ? ? ? float fraction = (float) (-2 * Math.cos((ratio + 1) * Math.PI) / 5.0f) + 0.1f;
? ? ? ? return fraction < 0.10f ? 0.10f : fraction;
? ? }
?
? ? @Override
? ? public boolean isPullEnable() {
? ? ? ? return pullEnabled;
? ? }
?
? ? @Override
? ? public boolean isCanPullStart() {
? ? ? ? if (child instanceof RecyclerView) {
? ? ? ? ? ? RecyclerView recyclerView = (RecyclerView) child;
? ? ? ? ? ? return !recyclerView.canScrollVertically(-1);
? ? ? ? }
? ? ? ? if (child instanceof AbsListView) {
? ? ? ? ? ? AbsListView lv = (AbsListView) child;
? ? ? ? ? ? return !lv.canScrollVertically(-1);
? ? ? ? }
? ? ? ? if (child instanceof RelativeLayout
? ? ? ? ? ? ? ? || child instanceof FrameLayout
? ? ? ? ? ? ? ? || child instanceof LinearLayout
? ? ? ? ? ? ? ? || child instanceof WebView
? ? ? ? ? ? ? ? || child instanceof View) {
? ? ? ? ? ? return child.getScrollY() == 0;
? ? ? ? }
? ? ? ? return false;
? ? }
?
? ? @Override
? ? public boolean isCanPullEnd() {
? ? ? ? if (child instanceof RecyclerView) {
? ? ? ? ? ? RecyclerView recyclerView = (RecyclerView) child;
? ? ? ? ? ? return !recyclerView.canScrollVertically(1);
? ? ? ? }
? ? ? ? if (child instanceof AbsListView) {
? ? ? ? ? ? AbsListView lv = (AbsListView) child;
? ? ? ? ? ? int first = lv.getFirstVisiblePosition();
? ? ? ? ? ? int last = lv.getLastVisiblePosition();
? ? ? ? ? ? View view = lv.getChildAt(last - first);
? ? ? ? ? ? if (null == view) {
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? return (lv.getCount() - 1 == last) &&
? ? ? ? ? ? ? ? ? ? ? ? (view.getBottom() <= lv.getHeight());
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if (child instanceof ScrollView) {
? ? ? ? ? ? View v = ((ScrollView) child).getChildAt(0);
? ? ? ? ? ? if (null == v) {
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? return child.getScrollY() >= v.getHeight() - child.getHeight();
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if (child instanceof NestedScrollView) {
? ? ? ? ? ? View v = ((NestedScrollView) child).getChildAt(0);
? ? ? ? ? ? if (null == v) {
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? return child.getScrollY() >= v.getHeight() - child.getHeight();
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if (child instanceof WebView) {
? ? ? ? ? ? return (((WebView) child).getContentHeight() * ((WebView) child).getScale()) - (((WebView) child).getHeight() + ((WebView) child).getScrollY()) <= 10;
? ? ? ? }
? ? ? ? if (child instanceof RelativeLayout
? ? ? ? ? ? ? ? || child instanceof FrameLayout
? ? ? ? ? ? ? ? || child instanceof LinearLayout
? ? ? ? ? ? ? ? || child instanceof View) {
? ? ? ? ? ? return (child.getScrollY() == 0);
? ? ? ? }
? ? ? ? return false;
? ? }
?
? ? /**
? ? ?* 通過addView實現(xiàn)效果回彈效果
? ? ?*
? ? ?* @param replaceChildView 需要替換的View
? ? ?*/
? ? public void replaceAddChildView(View replaceChildView) {
? ? ? ? if (replaceChildView != null) {
? ? ? ? ? ? removeAllViews();
? ? ? ? ? ? child = replaceChildView;
? ? ? ? ? ? addView(replaceChildView);
? ? ? ? }
? ? }
?
? ? public void setPullEnabled(boolean enable) {
? ? ? ? pullEnabled = enable;
? ? }
?
? ? public interface OnBounceStateListener {
? ? ? ? public void onBounce();
?
? ? ? ? public void overBounce();
? ? }
?
? ? public void setOnBounceStateListener(OnBounceStateListener onBounceStateListener) {
? ? ? ? this.onBounceStateListener = onBounceStateListener;
? ? }
?
? ? @Override
? ? public boolean dispatchKeyEvent(KeyEvent event) {
? ? ? ? try {
? ? ? ? ? ? return super.dispatchKeyEvent(event);
? ? ? ? } catch (IllegalArgumentException | IllegalStateException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? return false;
? ? }
?
? ? @Override
? ? public void dispatchWindowFocusChanged(boolean hasFocus) {
? ? ? ? try {
? ? ? ? ? ? super.dispatchWindowFocusChanged(hasFocus);
? ? ? ? } catch (IllegalArgumentException | IllegalStateException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
?
?
}

二、注意要點

滑動結束的時候要防止動畫抖動

private void handlePointerUp(MotionEvent event, int type) {
? ? ? ? int pointerIndexLeave = event.getActionIndex();
? ? ? ? int pointerIdLeave = event.getPointerId(pointerIndexLeave);
? ? ? ? if (mPointerId == pointerIdLeave) {
? ? ? ? ? ? int reIndex = pointerIndexLeave == 0 ? 1 : 0;
? ? ? ? ? ? mPointerId = event.getPointerId(reIndex);
? ? ? ? ? ? // 調整觸摸位置,防止出現(xiàn)跳動
? ? ? ? ? ? downY = event.getY(reIndex);
? ? ? ? }
? ? }?

總結

以上就是文章的主要內容,實現(xiàn)了豎向滑動回彈的效果。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Flutter 狀態(tài)管理scoped model源碼解讀

    Flutter 狀態(tài)管理scoped model源碼解讀

    這篇文章主要為大家介紹了Flutter 狀態(tài)管理scoped model源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Android四大組件之broadcast廣播使用講解

    Android四大組件之broadcast廣播使用講解

    Android開發(fā)的四大組件分別是:活動(activity),用于表現(xiàn)功能;服務(service),后臺運行服務,不提供界面呈現(xiàn);廣播接受者(Broadcast Receive),勇于接收廣播;內容提供者(Content Provider),支持多個應用中存儲和讀取數(shù)據(jù),相當于數(shù)據(jù)庫,本篇著重介紹廣播組件
    2022-12-12
  • Android 截圖功能源碼的分析

    Android 截圖功能源碼的分析

    這篇文章主要介紹了Android 截圖功能源碼的分析的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • 實時獲取股票數(shù)據(jù)的android app應用程序源碼分享

    實時獲取股票數(shù)據(jù)的android app應用程序源碼分享

    本文我們分享一個實時獲取股票數(shù)據(jù)的android app應用程序源碼分享,可以作為學習使用,本文貼出部分重要代碼,需要的朋友可以參考下本文
    2015-09-09
  • Android實現(xiàn)雷達View效果的示例代碼

    Android實現(xiàn)雷達View效果的示例代碼

    這篇文章主要介紹了Android實現(xiàn)雷達View效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • android監(jiān)控sim卡有沒有服務示例(sim卡管理)

    android監(jiān)控sim卡有沒有服務示例(sim卡管理)

    android監(jiān)聽SIM卡有沒有服務,可以使用android.telephony.PhoneStateListener類來實現(xiàn),下面是一個簡單的小例子,大家參考使用吧
    2014-01-01
  • 詳解如何實現(xiàn)一個Kotlin函數(shù)類型

    詳解如何實現(xiàn)一個Kotlin函數(shù)類型

    這篇文章主要為大家詳細介紹了如何實現(xiàn)一個Kotlin函數(shù)類型,文中的實現(xiàn)方法講解詳細,具有一定的借鑒價值,需要的小伙伴可以跟隨小編一起學習一下
    2022-10-10
  • Flutter實現(xiàn)App功能引導頁

    Flutter實現(xiàn)App功能引導頁

    這篇文章主要為大家詳細介紹了Flutter實現(xiàn)App功能引導頁,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Android編程使用AlarmManager設置鬧鐘的方法

    Android編程使用AlarmManager設置鬧鐘的方法

    這篇文章主要介紹了Android編程使用AlarmManager設置鬧鐘的方法,結合具體實例分析了Android基于AlarmManager實現(xiàn)鬧鐘功能的設置、取消、顯示等相關操作技巧,需要的朋友可以參考下
    2017-03-03
  • native.js獲取手機硬件基本信息實例代碼android版

    native.js獲取手機硬件基本信息實例代碼android版

    本文為大家分享了native.js獲取手機硬件基本信息實例代碼android版包括手機MAC地址,手機內存大小,手機存儲空間大小,手機CPU信息等手機硬件基本信息
    2018-09-09

最新評論