Android面試題-終極解決ViewPager.setCurrentItem切換頁面閃瞎我的雙眼

2021-02-14 Android乾貨程式設計師

android面試題-okhttp內核剖析

android面試題- Volley源碼剖析



今天做項目用ViewPager.setCurrentItem 方法,如果兩個頁面相聚比較遠,就會閃瞎我的鈦合金雙眼,中間切換大概20個頁面,如下所示:


setCurrentItem第二個參數設置false,四不四很簡單,直接使用如下代碼:

ViewPager.setCurrentItem(position,false);

很不幸的是,使用上面的代碼會出現如下效果,扎心了老鐵:


從第一題點擊切換到第十八題,你會發現頁面顯示空白,如果從第十個頁面切換到第十五個頁面沒事,平時大家估計沒有發現這個bug,一般我們使用ViewPager都是底下5個tab頁面,從第一個切換到第五個沒事,之前我也以為把第二個參數設置false就行,今天才發現,原來如果當頁面比較少的時候,大概十個以內,一般沒有問題,如果超過十個頁面切換就會出現空白,加載不了數據,扎心了,提出解決方案吧,ViewPager滑動使用的是Scroll,咱們把Scroll的滑動時間duration 設置為0就行。

自定義一個Scroll類,用於控制ViewPager滑動速度:

public  class MScroller extends Scroller {  
private static final Interpolator sInterpolator = new Interpolator() {    public float getInterpolation(float t) {        t -= 1.0f;        
       return t * t * t * t * t + 1.0f;  }};
public boolean noDuration;
public void setNoDuration(boolean noDuration) {
   this.noDuration = noDuration;}  
public MScroller(Context context) {  
   this(context,sInterpolator);}  
public MScroller(Context context, Interpolator interpolator) {
     super(context, interpolator);}  
@Overridepublic void startScroll(int startX, int startY, int dx, int dy, int duration) {    
   if(noDuration)        
       super.startScroll(startX, startY, dx, dy, 0);  
   else     super.startScroll(startX, startY, dx, dy,duration);  }}

上面代碼可知:

1)動態判斷頁面是否需要滑動,如果不需要滑動,設置滑動時間為0;

為方便使用,定義一個輔助類

public class ViewPageHelper {    ViewPager viewPager;    MScroller scroller;
   public ViewPageHelper(ViewPager viewPager) {    
       this.viewPager = viewPager;        init();    }    
    public void setCurrentItem(int item){        setCurrentItem(item,true);    }  
    public MScroller getScroller() {  
           return scroller;    }    
    public void setCurrentItem(int item, boolean somoth){      
        int current=viewPager.getCurrentItem();      
               if(Math.abs(current-item)>1){            scroller.setNoDuration(true);            viewPager.setCurrentItem(item,somoth);            scroller.setNoDuration(false);        }else{            scroller.setNoDuration(false);            viewPager.setCurrentItem(item,somoth);        }    }  
    private void init(){        scroller=new MScroller(viewPager.getContext());        Class<ViewPager>cl=ViewPager.class;    
        try {            Field field=cl.getDeclaredField("mScroller");            field.setAccessible(true);  
                             field.set(viewPager,scroller);        } catch (NoSuchFieldException e) {            e.printStackTrace();        }catch (IllegalAccessException e){            e.printStackTrace();        }    }}

由上面代碼可知:

1)Math.abs(current-item)>1 ,通過數學函數判斷頁面相隔大於1,就設置頁面切換的動畫的時間為0。

2)這樣每次設置頁面的時候,通過 helper 就可以自動選擇是否有時間間隔了。

3)但是這樣有點麻煩,每次還要手動改,而且使用TabLayout或者ViewPagerIndicator的話,它會自動調用ViewPager的方法,無法使用Helper,所以可以採用自定一個ViewPager,代碼如下:

public class SuperViewPager extends ViewPager {
   private ViewPageHelper helper;  
     public SuperViewPager(Context context) {  
         this(context,null);    }  
    public SuperViewPager(Context context, AttributeSet attrs) {    
        super(context, attrs);        helper=new ViewPageHelper(this);   }  
    @Override    public void setCurrentItem(int item) {        setCurrentItem(item,true);    }  
    @Override    public void setCurrentItem(int item, boolean smoothScroll) {        MScroller scroller=helper.getScroller();  
        if(Math.abs(getCurrentItem()-item)>1){            scroller.setNoDuration(true);        
            super.setCurrentItem(item, smoothScroll);            scroller.setNoDuration(false);        }else{            scroller.setNoDuration(false);      
            super.setCurrentItem(item, smoothScroll);        }    }}

至此完美解決了,ViewPager.setCurrentItem切換頁面,效果如下:

相關焦點

  • 利用ViewPager+Fragment+slidingmenu側滑組件實現的小demo
    從圖上可以看到,demo上面有三個按鈕和一個包含3個Fragment頁面的ViewPager,另外左側滑能拉出一個左頁面。剛開始做的demo是直接用FragmentTabHost來實現的,並在這個基礎上繼承RelativeLayout寫了個布局,來實現頁面的側滑效果。那個demo的效果跟這個的主要差距就是三個tab之間只能通過點擊切換,沒有viewpager這樣的滑動切換效果。這個demo下面的三個按鈕其實是三個RadioButton,只是把它前面的圓點隱藏了(demo裡面沒好好弄按鈕上的背景效果了)。
  • Android統一風格 —— 主題
    123個微信小程序源碼分享(附下載)[乾貨]2017已來,最全面試總結——這些Android面試題你一定需要原文連結:http://frodoking.github.io而且更嚴重的是每個人都在自己的頁面中完成所有的業務處理,這種編碼能力筆者只能表示無語,本人最後把問題給他們拋出來後就離開了。本人在這裡必須說明一下,這種思想是非常錯誤的:1、風格不統一,那麼你會浪費更多的時間去寫xml布局。同時你並不能保證每個頁面真的統一了;2、Android App不是Activity的堆積。
  • 三年經驗 Android 開發面經總結
    在下2017年畢業,目前從事android開發工作已經3年啦,前段時間剛完成一次跳槽,面試了幾家公司,將一些面試經驗分享給大家,希望對大家有所幫助。簡歷首先是簡歷,一般找一個模板,填寫掌握的技能和項目經歷即可。
  • 三年啦,跳槽成功的Android開發面經總結!
    在下2017年畢業,目前從事android開發工作已經3年啦,前段時間剛完成一次跳槽,面試了幾家公司,將一些面試經驗分享給大家,希望對大家有所幫助。首先是簡歷,一般找一個模板,填寫掌握的技能和項目經歷即可。
  • 來開發一個wanandroid快應用吧
    想學習小程序的可以參考先吐槽下1.因為快應用剛出來,網上沒有教程(至少我今天在寫這個應用的時候,網上除了demo還是demo,而且demo是官網的demo)2.官網雖然有文檔,但是文檔還不完善,很多地方都不知道怎麼解決,寫這個應用真的是靠自己慢慢摸索寫出來的,本來還有幾個功能,因為實在找不出解決方法放棄了(待慢慢研究)。。。註:前幾步跟官方文檔教程基本一致,可跳過。
  • 玩Android 快應用已經開源啦~
    先吐槽下1.因為快應用剛出來,網上沒有教程(至少我今天在寫這個應用的時候,網上除了demo還是demo,而且demo是官網的demo)2.官網雖然有文檔,但是文檔還不完善,很多地方都不知道怎麼解決,寫這個應用真的是靠自己慢慢摸索寫出來的
  • Fragment 番外篇——TabLayout+ViewPager+Fragment
    並命名其為「Fragment最佳實踐」,作為想到單獨使用Fragment的用戶來說,這個說法並不誇大,它解決了許多用戶在使用Fragment時產生的這樣那樣可見或不可見的問題。不過Fragment還有其他的使用方式,就是我們本章要介紹的。(本來是介紹ListView的,等著ListView的讀者不好意思了,我會很快更新的。)
  • Android App國際化
    values表示默認的資源文件夾,即當Resource找不到匹配的資源時,會使用values文件夾下的資源。文件夾的命名必須都是小寫字符,否則在一些大小寫敏感的文件系統中可能會出錯。本文主要介紹Android App國際化過程中遇到的問題和解決方案。1.整理HardCodeApp國際化是要在保持App原功能不變的情況下,主要對字符串進行替換。
  • 度夏裝備更是閃瞎雙眼!
    然而在我的肉肉尚且掙扎在這高溫驕陽以及說來就來的暴雨摧慘的生死考驗時,在一位肉友的帶領下,見識了本地一位超級大神的肉肉,用一句流行語概括:閃瞎了雙眼!大神的肉肉在全國肉友中都很有名。但是我覺得,閃瞎雙眼的應是大神肉肉度夏的設備,下面讓我們一觀:
  • 可能是目前最全的《Android面試題及解析》(379頁)
    趁著這段時間,小夥伴們可以參考這份可能是市面上最全面的安卓面試題解析大全!從基礎到架構進階,包含了騰訊、百度、小米、阿里、樂視、美團、58、獵豹、360、新浪、搜狐等一線網際網路公司面試被問到的題目,涵蓋了初中高級安卓技術點。文章中所列主要為大綱部分,詳細內容可以在文末自行獲取哈!
  • 夢幻西遊:砸鍋賣鐵刷6件120腰帶,一個特效閃瞎雙眼
    原本以為6件裝備會涼,沒想在最後一個特效閃瞎雙眼,老闆這波不虧的!欲知更多《夢幻西遊》電腦版精彩八卦內容,敬請準時收看最新夢幻訊息,帶你探索神奇機率,領略全新夢幻西遊獨特奧秘。
  • 熬夜整理了一份Android高頻面試題集錦+開源框架實戰PDF
    5,面對UI卡頓,我們從哪些方面入手進行分析解決?……4. Android源碼(★★★★)1、事件分發機制是怎樣的?設計者為什麼要設置攔截?2、Android是如何通過View進行渲染的?3、Android App 安裝的流程是怎樣的?
  • 2020年底面試題
    不然要出問題,然後面試官估計看出我不想去,後面的流程就不走了。感受整體下來,快手、頭條的難些,其次是美團、猿輔導、滴滴,螞蟻和騰訊適中。面試基本每次都一個小時左右,視頻面試,都是面完一輪再約下一輪。hr面會短些。年前面試可能會出現職位沒那麼多,騰訊就屬於年前有點凍結hc了。其他的還好。
  • 是時候讓 Android Tools 屬性拯救你了
    你在耍我嗎?這麼簡單的列表拿出來幹嘛?哈哈,客觀不要著急。這個並不難實現,倘若我說這裡並沒有寫一行 Java 或者 Kotlin 代碼就實現了此效果,而只是在布局頁面預覽,你敢信嗎?上圖只是冰山一角,下面這張圖才是全貌:
  • Android 自定義View篇(十)實現跑馬燈垂直滾動效果
    ViewFlipper 相關屬性介紹方法描述isFlipping判斷 View 切換是否正在進行setFilpInterval設置 View 之間切換的時間間隔startFlipping開始 View 的切換,而且會循環進行stopFlipping停止 View 的切換setOutAnimation設置切換
  • 十二星座專屬迪士尼公主水晶鞋,每一款都超美,巨蟹座閃瞎雙眼!
    隨小編一起來看看十二星座專屬迪士尼公主水晶鞋吧,每一款都超美,巨蟹座閃瞎雙眼!水瓶座:寶嘉康蒂水瓶座女生的追求很高,作為水瓶女的戀人或是朋友,如果你一直對自己的生活自怨自艾,水瓶女會很瞧不上你的。寶嘉康蒂的裙下,單綁帶的高跟鞋十分具有民族風,很是涼爽,流蘇的設計很是適合這種膚色。這就是水瓶座的專屬迪士尼公主水晶鞋!
  • 一次Android面試心得及面試題總結
    作者:huison_ma來源:blog.csdn.net/qq_27053103/article/details/79564062從16年畢業至今,就職過兩家公司,大大小小項目做了幾個,非常感謝我的兩位老大,在我的android成長路上給予我很多指導,亦師亦友的關係。
  • Android新組件RecyclerView介紹,其效率更好
    今天我們首先來說為什麼要介紹這個新組件RecyclerView,因為前幾天我發布了一個常用面試題ListView的復用及如何優化的文章,介紹給一些開發者,但是我看到有關的反饋說:現在都不再用listview了,代替的是RecyclerView,確實是,但是用的畢竟是少數,所以可能很多人對於這個組件不是很了解,那麼我們就來介紹一下吧!
  • 最新優秀的通用Android應用架構:從建項目開始
    絕對乾貨-國內值得關注的官方API集合,很全很強大(必須收藏)[乾貨]2017已來,最全面試總結——這些Android面試題你一定需要來源:Jude95  --><item name="colorPrimary">@color/DeepPurple</item><item name="colorPrimaryDark">@color/DeepPurple900</item><item name="colorAccent">@color/Orange
  • 2020 前端面試:第一波面試題總結
    令我意外的是,近一個月收到多家公司的面試邀請。因此總結一波2020年最新面試題,希望對大家有所幫助!後面的答案為自行整理,如有疏漏,歡迎指正!面試總結以下面試均為電話面試一面構造函數 ,是一種特殊的方法。主要用來在創建對象時初始化對象。