a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Android > 正文

android開發(fā)教程之使用線程實現(xiàn)視圖平滑滾動示例

2020-04-11 11:52:30
字體:
供稿:網(wǎng)友

最近一直想做下拉刷新的效果,琢磨了好久,才走到通過onTouch方法把整個視圖往下拉的步驟,接下來就是能拉下來,松開手要能滑回去啊。網(wǎng)上看了好久,沒有找到詳細(xì)的下拉刷新的例子,只有自己慢慢琢磨了。昨天和今天,研究了兩天,下拉之后回滾回去的效果終于今天做出來了!開心?,F(xiàn)在來分享下我的實現(xiàn)方法和一些心得體會吧。
我看了網(wǎng)上一個大神的例子,發(fā)現(xiàn)是在onTouch里面使用View的scrollTo(int, int)方法,來使整個視圖往下滾動的,我嘗試了使用setTranslationY()來對視圖進(jìn)行回滾,第一次是沒問題的,但多滾動幾次之后,整個視圖實際上已經(jīng)到了非?!案摺钡牡胤搅?,要拉很長的距離才能看到內(nèi)容。所以回滾也必須使用scrollTo(int, int)方法來操作。
但scrollTo(int, int)執(zhí)行是瞬間的,方法名講是滾動到,實際上就是“瞬移到”某個位置,因此需要一步一步的去瞬移它,讓它看上去是滾過去的……

因為等下要去跑步了,還有就是也沒有什么很多的要點需要講解,我就直接上代碼給大家看,注釋都寫好了,要點會單獨提一下,更詳細(xì)的講解與心得就等著我哪天把下拉刷新實現(xiàn)了吧。

復(fù)制代碼 代碼如下:

/**
     * @desc    平滑滾動
     * @param    v        需要操控的視圖
     * @param    fromY    起始Y坐標(biāo)
     * @param    toY        終止Y坐標(biāo)
     * @param    fps        幀率
     * @param    durtion    動畫完成時間(毫秒)   
     * */
    private void smoothScroll(View v, int fromY, int toY, int fps, long durtion) { 
        smoothScrollThread = new SmoothScrollThread(v, fromY, toY, durtion, fps);
        smoothScrollThread.run();
    }

    /**
     * @desc    平滑滾動線程,用于遞歸調(diào)用自己來實現(xiàn)某個視圖的平滑滾動
     * */
    class SmoothScrollThread implements Runnable {   
        //需要操控的視圖
        private View v = null;     
        //原Y坐標(biāo)
        private int fromY = 0; 
        //目標(biāo)Y坐標(biāo)
        private int toY = 0;     
        //動畫執(zhí)行時間(毫秒)
        private long durtion = 0;     
        //幀率
        private int fps = 60;      
        //間隔時間(毫秒),間隔時間 = 1000 / 幀率
        private int interval = 0;  
        //啟動時間,-1 表示尚未啟動
        private long startTime = -1;
        /減速插值器
        private DecelerateInterpolator decelerateInterpolator = null;

        /**
         * @desc    構(gòu)造方法,做好第一次配置
         * */
        public SmoothScrollThread(View v, int fromY, int toY, long durtion, int fps) {
            this.v = v;
            this.fromY = fromY;
            this.toY = toY;
            this.durtion = durtion;
            this.fps = fps;
            this.interval = 1000 / this.fps;      
            decelerateInterpolator = new DecelerateInterpolator();
        }
        @Override
        public void run() {
            //先判斷是否是第一次啟動,是第一次啟動就記錄下啟動的時間戳,該值僅此一次賦值
            if (startTime == -1) {
                startTime = System.currentTimeMillis();
            }         
            //得到當(dāng)前這個瞬間的時間戳
            long currentTime = System.currentTimeMillis();     
            //放大倍數(shù),為了擴(kuò)大除法計算的浮點精度
            int enlargement = 1000;         
            //算出當(dāng)前這個瞬間運(yùn)行到整個動畫時間的百分之多少
            float rate = (currentTime - startTime) * enlargement / durtion;          
            //這個比率不可能在 0 - 1 之間,放大了之后即是 0 - 1000 之間
            rate = Math.min(rate, 1000);          
            //將動畫的進(jìn)度通過插值器得出響應(yīng)的比率,乘以起始與目標(biāo)坐標(biāo)得出當(dāng)前這個瞬間,視圖應(yīng)該滾動的距離。
            int changeDistance = (int) ((fromY - toY) * decelerateInterpolator.getInterpolation(rate / enlargement));           
            int currentY = fromY - changeDistance;          
            v.scrollTo(0, currentY);           
            if (currentY != toY) {
                postDelayed(this, this.interval);
            } else {
                return;
            }
        }  
        public void stop() {
            removeCallbacks(this);
        }
    }

一些要點:

1.使用線程的目的是可以遞歸的調(diào)用自己,在每個run()方法里只滾動一點點,這個一點點根據(jù)幀率和插值器來決定。

2.插值器實際上就是一個函數(shù)(數(shù)學(xué)里的函數(shù)),輸入0-1之間的浮點數(shù),輸出0-1之間的浮點數(shù),輸出的曲線是什么樣的,就看是什么插值器了,decelerate就是減速插值器了,在平面直角坐標(biāo)系里面,x值均勻變化,y軸的變化越來越慢。

3.放大倍數(shù)(就是那里乘以1000)是為了提高精度,因為通過實踐發(fā)現(xiàn)用已經(jīng)過的毫秒數(shù)除以整個動畫周期得出的結(jié)果是0.0 -> 0.0 -> 0.0 -> 0.0 -> 1.0 -> 1.0 -> 1.0 -> 1.0 -> 1.0 -> 2.0 -> 2.0 -> 2.0,雖然是浮點數(shù),但精度卻莫名的保持在個位數(shù)上,乘以1000后,便會出現(xiàn)0-1000的均勻變化,這個時候去除以1000,便可得到0.000 - 1.000之間的均勻變化的數(shù)。

4.還有個很奇葩的是MotionEvent.getY()的值和scrollTo(int,int)的值貌似不是在同一個坐標(biāo)系里面的。這個還有待進(jìn)一步的分析和研究啊。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产精品91久久久久 | www91在线观看 | 亚洲国产一区二 | 五月天婷婷综合 | 色婷婷综合久久久中文字幕 | 亚洲欧美日韩在线 | 精品精品久久 | 亚洲高清电影 | 日韩视频一区二区三区 | 亚洲成人在线观看视频 | 国产婷婷精品av在线 | 密桃av| 久久久国产精品 | 澳门久久| 国产精品视频久久久久 | 午夜精品久久久久久久久久久久 | 国产精品国产成人国产三级 | 欧美成人精品一区二区男人看 | 99re6在线视频精品免费 | 精品一区二区三区四区五区 | 日韩欧美国产一区二区 | 免费观看av| 一区在线观看视频 | 亚洲黄色一区二区三区 | 久久免费精品 | 欧美成人精品在线观看 | 国产ts人妖另类 | 日韩精品一区二区三区四区 | 91麻豆精品国产91久久久更新时间 | 国产成人精品视频 | 毛片一区二区三区 | 久久国产久 | 91九色最新 | 日韩欧美国产网站 | 国产一区二区三区精品久久久 | 日韩无在线 | 久久精品国产一区二区电影 | 久久精品99 | 中文字幕免费在线 | 国产精品第一国产精品 | 影音先锋亚洲资源 |