Android的ScrollView的滾動的監聽以及屏幕靜止狀態的監聽實現

我在開發的過程中,用到了ScrollView,然後滾動的時候需要在底部顯示出一個向上的箭頭,點擊可以返回我們的屏幕的頂端。

這裏實現返回屏幕的頂端的代碼網上搜索有很多,其中有listview的返回頂端和scrollview的返回頂端,本人這裏給大家介紹一下scrollview的,在監聽的地方加入如下代碼:

scrollView.fullScroll(ScrollView.FOCUS_UP);
而ListView的返回頂端如下:

setListViewPos(0);
上面的是一個簡單的小插曲,主要給自己加一個小記錄。下面介紹正題:

在實現的過程中,首先使用了自定義的一個MyScrollView:

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * Created by Administrator on 2016/8/11 0011.
 */
public class MyScrollView extends ScrollView {
    private OnScrollListener onScrollListener;
    //用在用戶手指離開MyScrollViewMyScrollView還在繼續滑動,用來保存Y的距離
    private int lastScrollY;

    public MyScrollView(Context context) {
        this(context, null);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    //寫一個onScrollListener的監聽回調方法
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }


    //用於用戶手指離開MyScrollView的時候獲取MyScrollView滾動的Y距離,然後回調給onScroll方法中
    private Handler handler = new Handler() {

        public void handleMessage(android.os.Message msg) {
            int scrollY = MyScrollView.this.getScrollY();

            //此時的距離和記錄下的距離不相等,在隔5毫秒給handler發送消息
            if(lastScrollY != scrollY){
                lastScrollY = scrollY;
                handler.sendMessageDelayed(handler.obtainMessage(), 5);
            }
            if(onScrollListener != null){
                onScrollListener.onScroll(scrollY);
            }

        };

    };
    /**
     * 重寫onTouchEvent, 當用戶的手在MyScrollView上面的時候,
     * 直接將MyScrollView滑動的Y方向距離回調給onScroll方法中,當用戶擡起手的時候,
     * MyScrollView可能還在滑動,所以當用戶擡起手我們隔5毫秒給handler發送消息,在handler處理
     * MyScrollView滑動的距離
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(onScrollListener != null){
            onScrollListener.onScroll(lastScrollY = this.getScrollY());
        }
        switch(ev.getAction()){
            case MotionEvent.ACTION_UP:
                handler.sendMessageDelayed(handler.obtainMessage(), 5);
                break;
        }
        return super.onTouchEvent(ev);
    }
    //滾動的回調接口
    public interface OnScrollListener{
        //返回滑動的Y的距離
        public void onScroll(int scrollY);
    }
}
這個是繼承了ScrollView的,所以我們在使用的時候,依然保持着ScrollView的一些特性,ScrollView下面只能有一個佈局。在使用的過程中大家注意,xml的文件,我這邊就不貼出來了,太長了。大家根據自己的情況,在最外層套一個自定義好的MyScrollView即可。

然後,我們開始正片環節:

首先對我們自定義的MyScrollView聲明變量並且獲取資源。

private MyScrollView home_scroll;

home_scroll = (MyScrollView) findViewById(R.id.home_scroll);
接下來就是對scroll進行滾動的監聽啦。

home_scroll.setOnScrollListener(new MyScrollView.OnScrollListener() {
            @Override
            public void onScroll(int scrollY) {
                if (scrollY >= 100) {
                    home_btn_set.setVisibility(View.VISIBLE
);
                } else {
                    home_btn_set.setVisibility(View.GONE);     
                }
            }
        });
這個監聽很好理解啦,當我們滾動的距離大於100的時候,我們的返回頂部的按鈕顯示,否則隱藏。這部分根據自己的需求來進行設定 。

但是有時候這個監聽並不能很好的完成我們的需求。

有時候我們不僅僅需要監聽他滾動的距離,還需要監聽屏幕現在的狀態是否是滾動的還是靜止的。這時候就需要接下來的東西了:

home_scroll.setOnTouchListener(new View.OnTouchListener() {
            private int lastY = 0;
            private int touchEventId = -9983761;
            Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    View scroller = (View) msg.obj;
                    if (msg.what == touchEventId) {
                        if (lastY == scroller.getScrollY()) {
                            handleStop(scroller);
                        } else {
                            handler.sendMessageDelayed(handler.obtainMessage(touchEventId, scroller), 20);
                            lastY = scroller.getScrollY();
                        }
                    }
                }
            };

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    handler.sendMessageDelayed(handler.obtainMessage(touchEventId, v), 20);
                }
                return false;
            }

            //這裏寫真正的事件
            private void handleStop(Object view) {
                MyScrollView scroller = (MyScrollView) view;
		     home_btn_set.setVisibility(View.VISIBLE);
                
            }
        });
這部分利用我們的onTouchListener()通過handler來進行實時的監聽,當你不在觸碰屏幕的時候,屏幕還在繼續滑動,20毫秒發送一條消息,然後判斷現在的位置。最後的停止以後的事件處理就是在我們的handleStop中進行定義啦。

這些是我自己的一些個人方面的理解,希望能夠幫助大家,也可能有些片面,希望有意見的朋友也能夠互相交流,互相進步。謝謝。

發佈了57 篇原創文章 · 獲贊 8 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章