1. 程式人生 > >android ListView 仿IOS 回彈效果

android ListView 仿IOS 回彈效果

最近看IOS的下拉效果感覺很不錯,當拉倒最上面和最下面的時候繼續拉動會有緩衝,想在android裡面也做一個,到網上到處找,沒有找到好的方法,據說android新的API對ListView有這樣的支援,感覺不是特別好用。

自己利用scroller實現了一下,廢話不多說了直接上程式碼,就一個ListViewEx類,程式碼很簡單,有點小技巧,註釋就不寫了,很容易看懂

大家不好意思上次發的那個程式碼有點問題,這次重新修改了一下,對不住大家,發錯了程式碼。難過,部落格發的少,大家理解一下




import android.app.ActionBar.Tab;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.Scroller;


public class ListViewEx extends ListView implements OnScrollListener {


    private float lastX;
    private float lastY;
    private final static float RATIO = 2.25f;
    private int startY;
    private int state;


    private boolean isRecored;


    private Scroller mScroller;


    public static final int STATUS_FOOTER_IDLE = 0;
    public static final int STATUS_FOOTER_LOADING = 1;
    public static final int STATUS_FOOTER_DONE = 2;
    public static final int STATUS_FOOTER_NET_ERROR = 3;
    public static final int STATUS_FOOTER_REFRESHING = 4;
    private int footerStatus = STATUS_FOOTER_IDLE;


    private int lastPos, totalCount;


    private boolean isBottom = false;
    private boolean isTop = true;


    public int getFooterStatus() {
        return footerStatus;
    }


    public void setFooterStatus(int footerStatus) {
        this.footerStatus = footerStatus;
    }


    public int getState() {
        return state;
    }


    public ListViewEx(Context context) {
        this(context, true);
    }


    public ListViewEx(Context context, boolean isEnabled) {
        super(context);
        init(context);
    }


    public ListViewEx(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }


    private void init(Context context) {
        mScroller = new Scroller(getContext());
        setOnScrollListener(this);
    }


    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {


    }


    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {


        if (firstVisibleItem == 0) {
            isTop = true;
        } else {
            isTop = false;
        }


        lastPos = view.getLastVisiblePosition();
        totalCount = totalItemCount;
        if (lastPos == totalCount - 1) {
            isBottom = true;


        } else {
            isBottom = false;
        }


    }


    float lastDx;
    float lastDy;
    boolean record = false;


    public boolean dispatchTouchEvent(MotionEvent ev) {
        float x = ev.getX();
        float y = ev.getY();


        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                record = false;
                lastDx = x;
                lastDy = y;


                break;
            case MotionEvent.ACTION_MOVE: {
                final float deltaX = Math.abs(x - lastDx);
                final float deltaY = Math.abs(y - lastDy);


                if (deltaX > 0 && deltaX > deltaY) {
                    record = true;
                } else {
                    record = false;
                }
            }
                break;


            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                isRecored = false;
                break;


        }
        return super.dispatchTouchEvent(ev);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {


        float x = ev.getX();
        float y = ev.getY();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:


                lastX = x;
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                final float deltaX = Math.abs(x - lastX);
                final float deltaY = Math.abs(y - lastY);
                if (deltaX > 0 && deltaX > deltaY) {
                    return false;


                } else {
                    float curY = ev.getY();


                    // if (curY - lastY > 0 && getScrollY() == 0) {
                    // top = true;
                    // bottom = false;
                    // } else if (curY - lastY < 0 && getScrollY() == getChildAt(0).getMeasuredHeight()) {
                    // top = false;
                    // bottom = false;
                    // } else {
                    // top = false;
                    // bottom = true;
                    //
                    // }
                    getParent().requestDisallowInterceptTouchEvent(false);
                }


                break;


            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                requestDisallowInterceptTouchEvent(false);
                break;
        }


        return super.onInterceptTouchEvent(ev);


    }


    private int distance;


    @Override
    public void computeScroll() {


        // 先判斷mScroller滾動是否完成
        if (mScroller.computeScrollOffset()) {


            // 這裡呼叫View的scrollTo()完成實際的滾動
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());


            // 必須呼叫該方法,否則不一定能看到滾動效果
            postInvalidate();
        }
        super.computeScroll();
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {


        switch (ev.getAction()) {


            case MotionEvent.ACTION_DOWN:


                if (!isRecored) {
                    isRecored = true;
                    startY = (int) ev.getY();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isTop || isBottom) {
                    changeViewByState();
                }


                isRecored = false;


                break;


            case MotionEvent.ACTION_MOVE:


                int tempY = (int) ev.getY();
                if (!isRecored) {
                    isRecored = true;
                    startY = tempY;
                }
                if (isBottom && isTop) {
                    distance = (int) ((tempY - startY) / RATIO);
                    smoothTo(0, -distance);


                    // smoothTo(0, -distance);
                } else {
                    if (isTop) {
                        if (tempY - lastY > 0) {
                            distance = (int) ((tempY - startY) / RATIO);
                            smoothTo(0, -distance);


                            // smoothTo(0, -distance);
                        }
                    } else if (isBottom) {
                        if (tempY - lastY < 0) {
                            distance = (int) ((tempY - startY) / RATIO);
                            smoothTo(0, -distance);


                            // smoothTo(0, -distance);
                        }
                    }
                }


                // else if (tempY - lastY < 0 && getScrollY() == getChildAt(0).getMeasuredHeight()) {
                // distance =
                // (int) ((tempY - startY) / RATIO);
                // smoothTo(0, -distance);
                // }
                break;


            default:
                break;
        }
        return super.onTouchEvent(ev);
    }


    private final void smoothScrollToNormal() {
        smoothTo(0, 0);
    }


    private void smoothTo(int fx, int fy) {
        int dx = fx - mScroller.getFinalX();
        int dy = fy - mScroller.getFinalY();
        mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
        invalidate();
    }


    private void changeViewByState() {
        smoothScrollToNormal();
        distance = 0;
    }


}

相關推薦

android ListView 仿IOS 效果

最近看IOS的下拉效果感覺很不錯,當拉倒最上面和最下面的時候繼續拉動會有緩衝,想在android裡面也做一個,到網上到處找,沒有找到好的方法,據說android新的API對ListView有這樣的支援,感覺不是特別好用。 自己利用scroller實現了一下,廢話不多說了直接

Android中自定義仿IOS效果ListView

ios中有一個控制元件回彈的效果,比如listview ,拉動到第一條或者最後一條資料的時候,還可以繼續拉動,鬆手就回彈到原來位置,很贊,其實在android中實現起來也非常簡單,我們只需要重寫listview的下面兩個 方法即可 先上圖 @Override pub

仿IOS效果支援任何控制元件

效果圖: 匯入依賴: dependencies { // ... compile 'me.everything:overscroll-decor-android:1.0.4

自定義帶滑動距離監控和仿iOS效果的NestedScrollView

  在最近的Support Library更新中(25.3.0),新增或者修復了許多東西,具體可以看revisions,其中有一個新增的動畫效果:SpringAnimation 即彈簧動畫,SpringAnimation是一個受SpringForce驅動的動畫。彈簧力限定

新手自定義控制元件,建立屬於自己的下拉重新整理(一)---Android,ListView實現IOS的彈性效果

前言 相信很多童鞋對於控制元件的下拉重新整理都比較熟悉吧,常用的PullToRefresh開源庫和Google自帶的SwipeRefreshLayout大家肯定也很熟悉吧,但作為一個Android開發新手,對於自定義控制元件和自定義View來實現一些效果肯定還

android仿IOS頁面效果

碼農同學們做過手機開發的相比一定對ios平臺頁面的上下回彈效果印象深刻,特別是android開發對此是各種嫉妒羨慕恨啊,在特效方面蘋果做的很好,做了很多,當然谷歌也不差,神馬特效咱們都能做出來,因為android開放更多,移植性也更好,so..我特麼手賤自己寫了一個上下拉動

Android仿ios底部出框效果

準備: public class ActionSheet { public interface OnActionSheetSelected { void onClick(int whichButton); } private ActionShee

iOS動畫效果

新建一個專案,然後在storyboard中放入一個View並用autolayout設定View的位置 和上邊的距離(設定Y) 離左邊的距離(設定X) 設定大小 給View拖一個輸出口 在viewDidLoad中新增給view新增拖動手勢

Android仿ios底部框,支援傳入list集合,任意配置個數

不說廢話,一看程式碼誰都懂。   public class BottomDialog { private Context context; private Dialog dialog; private TextView txt_title; p

Android 帶阻尼效果的ScorllView

import android.content.Context; import android.graphics.Color; import android.graphics.Rect; import android.util.AttributeSet; impo

Android HorizontalScrollView效果

轉載記錄備份查閱 import android.annotation.SuppressLint; import android.os.Build; import android.util.Log; import android.view.MotionEvent

Android滑動效果

原理: addHeaderView裡做的事: 1.測量出header的寬高,呼叫了measureView方法 2.設定LayoutParams,寬:MATCH_PARENT,高:10 3.設定topMargin的值為負的header的高度,即將header隱藏在螢幕最上方

Android 自定義ScrollView 支援慣性滑動,慣性效果。支援上拉載入更多

先講下原理: ScrollView的子View 主要分為3部分:head頭部,滾動內容,fooder底部 我們實現慣性滑動,以及回彈,都是靠超過head或者fooder 就重新滾動到  ,內容的頂部或者底部。 之前看了Pulltorefresh 他是通過不斷改變 head或

Android View 仿iOS SwitchButton和各種效果集合

自學android差不多有一年了,從最初的小白菜鳥,摸爬滾打,看大神們的部落格,android官網的api,某網站的視訊教學,github開源專案。奮鬥這麼久隱隱感覺自己可以脫離新手的身份了,交出這篇文章權當作andriod小學水準的畢業典禮。 iOS Switch

Android ScrollView效果(二)

上一篇文章說了那個效果不怎麼好,現在實現方法稍微變一下: import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.

android仿IOS水滴版上下拉重新整理的Listview

       之前有分享一些重新整理的Demo,最近找到一個重新整理的例子,分享給大家。同時感謝原作者的分享!        現在給大家分享一個高仿IOS的Listview重新整理效果,支援上下拉重新

仿ios的滑動效果

public 頭部 ati 設置 class iss generated ttr stat package code.suibianchou.com.custormview2;import android.annotation.SuppressLint;import and

-webkit-overflow-scrolling 與滾動效果.

插件 列表 卡住 快的 優雅 css 移動設備 分享 兼容性 參考來源:https://developer.mozilla.org/zh-CN/docs/Web/CSS/-webkit-overflow-scrolling      https://www.w3cways.

angual+mui 雙欄上拉加載,微信裏面禁用默認事件可用,可以防止瀏覽器效果

apply length data mui this reat mobile ng- a10 //html 部分 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Consolas; color: #2eafa9

自定義ScrollView 實現上拉下拉的效果--並且子控件中有Viewpager的情況

是否 AS abs pri tar utils lda animation ted onInterceptTouchEvent就是對子控件中Viewpager的處理:左右滑動應該讓viewpager消費 1 public class MyScrollView ext