亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

scroller機制

2019-11-09 15:51:34
字體:
來源:轉載
供稿:網友

參考《android開發藝術探索》 ,參考 http://blog.csdn.net/guolin_blog/article/details/48719871

package com.example.lenvov.com.widget;

import android.content.Context;import android.support.v4.view.ViewConfigurationCompat;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.widget.Scroller;/** * Created by lenvov on 2017/2/7. * 目的:View或者ViewGroup的內容發生移動時比較平滑或者有其他的移動漸變效果 * 原理--利用scroller實現滑動的工作機制 * 1)觸摸事件onTouchEvent獲取坐標,mScroller.startScroll保存參數,invalidate請求重繪View樹,即draw()過程 * 2)View的onDraw會調用computeScroll(空實現) * 3)我們重寫computeScroll,如果滾動未結束則滾動,接著調用invalidate請求再次重繪 * *通俗的理解: * 從上可見Scroller執行流程里面的三個核心方法 * mScroller.startScroll() * mScroller.computeScrollOffset() * view.computeScroll() * 1 在mScroller.startScroll()中為滑動做了一些初始化準備. *   比如:起始坐標,滑動的距離和方向以及持續時間(有默認值)等. *   其實除了這些,在該方法內還做了些其他事情: *   比較重要的一點是設置了動畫開始時間. * * 2 computeScrollOffset()方法主要是根據當前已經消逝的時間 *   來計算當前的坐標點并且保存在mCurrX和mCurrY值中. *   因為在mScroller.startScroll()中設置了動畫時間,那么 *   在computeScrollOffset()方法中依據已經消逝的時間就很容易 *   得到當前時刻應該所處的位置并將其保存在變量mCurrX和mCurrY中. *   除此之外該方法還可判斷動畫是否已經結束. * * 3mScroller.computeScrollOffset()判斷了滑動是否結束 *   2.1 返回false,滑動已經結束. *   2.2 返回true,滑動還沒有結束. *       并且在該方法內部也計算了最新的坐標值mCurrX和mCurrY. *       就是說在當前時刻應該滑動到哪里了. *       既然computeScrollOffset()如此貼心,盛情難卻啊! *       于是我們就覆寫View的computeScroll()方法, *       調用scrollTo(By)滑動到那里!滿足它的一番苦心吧. * */public class ScrollerLayout extends ViewGroup {    /**     * 用于完成滾動操作的實例     */    PRivate Scroller mScroller;    /**     * 判定為拖動的最小移動像素數     */    private int mTouchSlop;    /**     * 手機按下時的屏幕坐標     */    private float mXDown;    /**     * 手機當時所處的屏幕坐標     */    private float mXMove;    /**     * 上次觸發ACTION_MOVE事件時的屏幕坐標     */    private float mXLastMove;    /**     * 界面可滾動的左邊界     */    private int leftBorder;    /**     * 界面可滾動的右邊界     */    private int rightBorder;    public ScrollerLayout(Context context, AttributeSet attrs) {        super(context, attrs);        // 第一步,創建Scroller的實例        mScroller = new Scroller(context);        ViewConfiguration configuration = ViewConfiguration.get(context);        // 獲取TouchSlop值        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int childCount = getChildCount();        for (int i = 0; i < childCount; i++) {            View childView = getChildAt(i);            // 為ScrollerLayout中的每一個子控件測量大小            measureChild(childView, widthMeasureSpec, heightMeasureSpec);        }    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        if (changed) {            int childCount = getChildCount();            for (int i = 0; i < childCount; i++) {                View childView = getChildAt(i);                // 為ScrollerLayout中的每一個子控件在水平方向上進行布局 layout(int l, int t, int r, int b)                childView.layout(i * childView.getMeasuredWidth(), 0, (i + 1) * childView.getMeasuredWidth(), childView.getMeasuredHeight());            }            // 初始化左右邊界值            leftBorder = getChildAt(0).getLeft();            rightBorder = getChildAt(getChildCount() - 1).getRight();        }    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                mXDown = ev.getRawX();                mXLastMove = mXDown;                break;            case MotionEvent.ACTION_MOVE:                mXMove = ev.getRawX();                float diff = Math.abs(mXMove - mXDown);                mXLastMove = mXMove;                // 當手指拖動值大于TouchSlop值時,認為應該進行滾動,攔截子控件的事件                if (diff > mTouchSlop) {                    return true;                }                break;        }        return super.onInterceptTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        Log.v("srcoll_","MotionEvent.ACTION="+event.getAction()+";getScrollX()="+getScrollX());        switch (event.getAction()) {            case MotionEvent.ACTION_MOVE:                mXMove = event.getRawX();                int scrolledX = (int) (mXLastMove - mXMove);                if (getScrollX() + scrolledX < leftBorder) {                    scrollTo(leftBorder, 0);                    return true;                } else if (getScrollX() + getWidth() + scrolledX > rightBorder) {                    scrollTo(rightBorder - getWidth(), 0);                    return true;                }                scrollBy(scrolledX, 0);                mXLastMove = mXMove;                break;            case MotionEvent.ACTION_UP:                //Log.v("srcoll","MotionEvent.ACTION_UP");                // 當手指抬起時,根據當前的滾動值來判定應該滾動到哪個子控件的界面                int targetIndex = (getScrollX() + getWidth() / 2) / getWidth();                int dx = targetIndex * getWidth() - getScrollX();                // 第二步,調用startScroll()方法來初始化滾動數據并刷新界面                mScroller.startScroll(getScrollX(), 0, dx, 0);                invalidate();                break;        }        return super.onTouchEvent(event);    }    @Override    public void computeScroll() {        // 第三步,重寫computeScroll()方法,并在其內部完成平滑滾動的邏輯        if (mScroller.computeScrollOffset()) {// true表示滾動未結束,false表示滾動結束            Log.v("srcoll_","computeScroll getScrollX()="+getScrollX());            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());//獲取當前Scrollx Scrolly,通過scrollto滾動到            invalidate();        }else{            Log.v("srcoll_","");        }    }}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
午夜免费在线观看精品视频| 午夜精品一区二区三区在线视| 日韩av免费在线播放| 亚洲毛片在线观看| 国产精品美女久久久免费| 国产欧美日韩中文字幕| 精品亚洲夜色av98在线观看| 欧美日韩美女在线观看| 欧美激情在线视频二区| 国产精品久久久久秋霞鲁丝| 日本道色综合久久影院| 日本精品久久久| 国产精品亚洲片夜色在线| 国产日韩精品在线| 亚洲色图校园春色| 欧美日韩在线视频一区| 久久夜精品香蕉| 欧美丝袜第一区| 亚洲精品久久久久久下一站| 欧美日韩午夜视频在线观看| 国内成人精品一区| 92版电视剧仙鹤神针在线观看| 欧美日韩激情小视频| 亚洲第一福利视频| 成人天堂噜噜噜| 国产亚洲精品久久久久久| 日韩欧美精品网址| 欧美激情三级免费| 岛国av一区二区在线在线观看| 亚洲成人黄色在线| 亚洲欧美国内爽妇网| 人九九综合九九宗合| 在线亚洲午夜片av大片| 亚洲免费人成在线视频观看| 久久免费精品日本久久中文字幕| 欧美与黑人午夜性猛交久久久| 日韩视频永久免费观看| 日韩av在线免费观看一区| 欧美xxxx做受欧美.88| 欧美性感美女h网站在线观看免费| 狠狠躁夜夜躁人人躁婷婷91| 欧美电影免费观看电视剧大全| 日韩精品免费在线观看| 精品无人区乱码1区2区3区在线| 91沈先生作品| 欧美激情网站在线观看| 大伊人狠狠躁夜夜躁av一区| 亚洲精品天天看| 国外成人免费在线播放| 日本精品视频网站| 亚洲激情在线视频| 欧美中文字幕在线播放| 亚洲精品国产美女| 亚洲男人天堂2019| 亚洲黄色有码视频| 国产精品久久久久久久久男| 亚洲欧美精品在线| 国产精品96久久久久久又黄又硬| 久久夜色精品国产亚洲aⅴ| 亚洲影影院av| 日韩精品中文在线观看| 日韩精品中文在线观看| 欧美视频在线观看 亚洲欧| 日韩欧美一区二区三区久久| 国产成人在线一区| 精品伊人久久97| 狠狠色噜噜狠狠狠狠97| 成人中文字幕在线观看| 日韩亚洲欧美成人| 久久99国产综合精品女同| 欧美激情精品久久久久久免费印度| 中文字幕在线国产精品| 日本国产欧美一区二区三区| 中文字幕在线成人| 欧美日韩国产一区在线| 久久精品国产亚洲7777| 亚洲精品一区二区三区婷婷月| 91黄色8090| 精品呦交小u女在线| 亚洲情综合五月天| 91精品综合久久久久久五月天| 91精品久久久久久久久久另类| 国产精品电影网| 97在线观看视频国产| 综合激情国产一区| 97久久国产精品| 97人人爽人人喊人人模波多| 永久免费看mv网站入口亚洲| 亚洲国产欧美一区| 伊人一区二区三区久久精品| 久久亚洲精品毛片| 午夜精品一区二区三区视频免费看| 亚洲最新av网址| 欧美视频免费在线观看| 国产精品91一区| 欧美日韩高清在线观看| 亚洲天堂免费在线| 91免费综合在线| 中文字幕亚洲在线| 日韩一区视频在线| 欧美精品激情在线| 国产一区二区三区网站| 国产中文欧美精品| 亚洲精品av在线播放| 日韩综合视频在线观看| 揄拍成人国产精品视频| 欧美影院成年免费版| 色噜噜国产精品视频一区二区| 第一福利永久视频精品| 青草热久免费精品视频| 日韩福利视频在线观看| 国产999精品视频| 一区二区福利视频| 5278欧美一区二区三区| 欧美极度另类性三渗透| 亚洲欧美中文字幕在线一区| 欧美性jizz18性欧美| zzjj国产精品一区二区| 久久综合色88| 国产亚洲一级高清| 国产成人a亚洲精品| 国产一区在线播放| 精品久久久久人成| 久久色免费在线视频| 欧美成人在线免费视频| 中文字幕一区二区三区电影| 国产精品美女无圣光视频| 9.1国产丝袜在线观看| 色悠久久久久综合先锋影音下载| 91精品国产99久久久久久| 国产精品女人网站| 欧美中文字幕在线观看| 中文字幕精品视频| 欧美激情精品久久久久久免费印度| 欧美一级大片在线观看| 色婷婷亚洲mv天堂mv在影片| 亚洲欧美国产精品久久久久久久| 亚洲第一页在线| 在线观看日韩欧美| 日韩黄色在线免费观看| 91精品国产成人| 亚洲美女激情视频| 欧美精品久久久久a| 亚洲色图35p| 国产精品亚洲欧美导航| 欧美激情xxxx性bbbb| 在线一区二区日韩| 懂色aⅴ精品一区二区三区蜜月| 日韩视频免费在线| 欧美一区二区视频97| 亚洲国产高清福利视频| 国产精品美女在线观看| 国产精品扒开腿做爽爽爽的视频| 2019中文字幕在线观看| 日韩国产欧美精品一区二区三区| 日韩av在线影院| 少妇高潮久久77777| 国产精品直播网红| 欧美在线视频一区| 欧美大片免费看| 青草青草久热精品视频在线观看| 91精品久久久久久久久久另类| 午夜精品久久久久久久99黑人| 精品久久久精品|