国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

scroller機(jī)制

2019-11-09 17:07:16
字體:
供稿:網(wǎng)友

參考《android開發(fā)藝術(shù)探索》 ,參考 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的內(nèi)容發(fā)生移動時比較平滑或者有其他的移動漸變效果 * 原理--利用scroller實(shí)現(xiàn)滑動的工作機(jī)制 * 1)觸摸事件onTouchEvent獲取坐標(biāo),mScroller.startScroll保存參數(shù),invalidate請求重繪View樹,即draw()過程 * 2)View的onDraw會調(diào)用computeScroll(空實(shí)現(xiàn)) * 3)我們重寫computeScroll,如果滾動未結(jié)束則滾動,接著調(diào)用invalidate請求再次重繪 * *通俗的理解: * 從上可見Scroller執(zhí)行流程里面的三個核心方法 * mScroller.startScroll() * mScroller.computeScrollOffset() * view.computeScroll() * 1 在mScroller.startScroll()中為滑動做了一些初始化準(zhǔn)備. *   比如:起始坐標(biāo),滑動的距離和方向以及持續(xù)時間(有默認(rèn)值)等. *   其實(shí)除了這些,在該方法內(nèi)還做了些其他事情: *   比較重要的一點(diǎn)是設(shè)置了動畫開始時間. * * 2 computeScrollOffset()方法主要是根據(jù)當(dāng)前已經(jīng)消逝的時間 *   來計算當(dāng)前的坐標(biāo)點(diǎn)并且保存在mCurrX和mCurrY值中. *   因?yàn)樵趍Scroller.startScroll()中設(shè)置了動畫時間,那么 *   在computeScrollOffset()方法中依據(jù)已經(jīng)消逝的時間就很容易 *   得到當(dāng)前時刻應(yīng)該所處的位置并將其保存在變量mCurrX和mCurrY中. *   除此之外該方法還可判斷動畫是否已經(jīng)結(jié)束. * * 3mScroller.computeScrollOffset()判斷了滑動是否結(jié)束 *   2.1 返回false,滑動已經(jīng)結(jié)束. *   2.2 返回true,滑動還沒有結(jié)束. *       并且在該方法內(nèi)部也計算了最新的坐標(biāo)值mCurrX和mCurrY. *       就是說在當(dāng)前時刻應(yīng)該滑動到哪里了. *       既然computeScrollOffset()如此貼心,盛情難卻啊! *       于是我們就覆寫View的computeScroll()方法, *       調(diào)用scrollTo(By)滑動到那里!滿足它的一番苦心吧. * */public class ScrollerLayout extends ViewGroup {    /**     * 用于完成滾動操作的實(shí)例     */    PRivate Scroller mScroller;    /**     * 判定為拖動的最小移動像素數(shù)     */    private int mTouchSlop;    /**     * 手機(jī)按下時的屏幕坐標(biāo)     */    private float mXDown;    /**     * 手機(jī)當(dāng)時所處的屏幕坐標(biāo)     */    private float mXMove;    /**     * 上次觸發(fā)ACTION_MOVE事件時的屏幕坐標(biāo)     */    private float mXLastMove;    /**     * 界面可滾動的左邊界     */    private int leftBorder;    /**     * 界面可滾動的右邊界     */    private int rightBorder;    public ScrollerLayout(Context context, AttributeSet attrs) {        super(context, attrs);        // 第一步,創(chuàng)建Scroller的實(shí)例        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中的每一個子控件在水平方向上進(jìn)行布局 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;                // 當(dāng)手指拖動值大于TouchSlop值時,認(rèn)為應(yīng)該進(jìn)行滾動,攔截子控件的事件                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");                // 當(dāng)手指抬起時,根據(jù)當(dāng)前的滾動值來判定應(yīng)該滾動到哪個子控件的界面                int targetIndex = (getScrollX() + getWidth() / 2) / getWidth();                int dx = targetIndex * getWidth() - getScrollX();                // 第二步,調(diào)用startScroll()方法來初始化滾動數(shù)據(jù)并刷新界面                mScroller.startScroll(getScrollX(), 0, dx, 0);                invalidate();                break;        }        return super.onTouchEvent(event);    }    @Override    public void computeScroll() {        // 第三步,重寫computeScroll()方法,并在其內(nèi)部完成平滑滾動的邏輯        if (mScroller.computeScrollOffset()) {// true表示滾動未結(jié)束,false表示滾動結(jié)束            Log.v("srcoll_","computeScroll getScrollX()="+getScrollX());            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());//獲取當(dāng)前Scrollx Scrolly,通過scrollto滾動到            invalidate();        }else{            Log.v("srcoll_","");        }    }}
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 防城港市| 玉树县| 东丰县| 宜丰县| 洞头县| 雅安市| 岑巩县| 光山县| 保靖县| 徐汇区| 水富县| 黄陵县| 政和县| 武义县| 讷河市| 梁山县| 蕉岭县| 海盐县| 清河县| 永川市| 轮台县| 龙江县| 集贤县| 德格县| 玉门市| 黄陵县| 湖口县| 海城市| 子洲县| 策勒县| 宜兴市| 得荣县| 临沭县| 宜章县| 微山县| 波密县| 瑞丽市| 邯郸市| 河曲县| 津南区| 神农架林区|