如何让fragment刷新界面_快速实现android版抖音主界面的心得
原文作者:DK_BurNIng
如何快速確定競品某個界面的實現方式?
當你收到產品一個需求是模仿某個競品且時間很短沒有過多時間給你調研技術方案的時候,如何盡快確定這個功能的技術方案呢? 這里我給出我自己的一個小竅門,可以避免走彎路,比如先確定的方案到最后發現各種各樣的原因方案不行,導致最后臨時變更 方案,需求延期發布的悲劇。。。
- Androidsdkools 首先去這個目錄下 找到 monitor這個可執行文件,然后打開你想模仿的競品頁面,然后執行這個文件。
比方說抖音的主界面這種滑動整屏的東西,相信之前很多人都沒做過,很多人可能以為recyclerview可以拿來做這種場景,實際上recyclerview確實可以做,但是抖音這里能看出來卻是使用了viewpager來做。作為一個模仿者,為了少走彎路, 那么顯然 我們也是優先要選擇viewpager的。
- 其次用這個軟件,還可以看出來界面上的某個控件所屬的id。這個id很重要,后面我們反編譯的時候可以通過全局 搜索這個id 找到大概的源碼位置,雖然都是混淆過的代碼,但是大致還是能分析出一些技術細節的。 這里注意一點:很多阿里系的產品用這個方法你分析界面的時候你會發現根本沒有id可以捕捉到,放心這并不是什么 阿里的黑科技反 反編譯技術,而是阿里使用了諸如weex react native等類似的方案,當使用這種方案的時候, 我們是找不到id的噢,如果你大致了解weex react-native的實現方案的話你應該明白我在說些什么。
- 反編譯就用jadx就可以,足夠使用。在用jadx反編譯之后搜索你之前的id,就可以大概找到對應的代碼位置,我就是通過 這個手段,確定了抖音使用的垂直的viewpager到底是出自于github上哪個開源控件。。。為了避免法律糾紛我這里就 不明說是用的哪個開源的垂直滑動的viewpager,有興趣的同學可以自己玩一玩。
- adb shell dumpsys activity | grep mFocusedActivity 這個命令是神器,可以把你當前正在顯示的activity的名字 打出來,方便你更加迅速的定位競品的代碼。。
不要小看這條命令哦,很多功能當你不知道競品是彈了一個popwindow還是一個dialoagfragment還是啟動了一個透明的activity的時候,這個方法就很有用了,可以避免走很多彎路。
總結一下模仿抖音主界面的時候遇到的一些問題和解決方案。
1、抖音整體技術方案是 垂直的viewpager+下拉刷新上拉加載控件+fragment的組合方案。不管是前者還是后者我們都有成熟的開源方案可以選擇,我們只是把他合并起來而已。這第一步其實并不難。
2、盡量使用FragmentStatePagerAdapter。FragmentPagerAdapter不推薦使用,可能平時我們用FragmentPagerAdapter更多, 但是要知道FragmentPagerAdapter是不會釋放內存的,你不可見的fragment也是常駐內存的,像抖音這種幾乎無限滑動的 短視頻方案,使用FragmentPagerAdapter肯定是爆內存oom的。而用 FragmentStatePagerAdapter的話,對于不可見的 fragment,系統是自動釋放內存的,內存里只會保留你能看到的fragment 和這個看到的fragment前后2個fragmnt。當然 這個值可以動態設置,但是至少都會保留3個fragment。
3、fragmentStatePagerAdapter.notifyDataSetChanged()失效? 有時候,notifyDataSetChanged方法調用了,界面卻沒有變化?實際上對于fragmentStatePagerAdapter來說,界面刷新不刷新 重繪不重繪 主要取決于getItemPosition方法的返回值,默認是返回 POSITION_UNCHANGED 也就是不重繪。只有 返回POSITION_NONE的時候才會重繪界面,重新繪制一遍fragemnt。 很多人不太理解什么意思,我簡單描述一下場景:
比如說,我們剛進抖音的主界面,假設返回了10條視頻數據,我們默認播第一條。展示的是第一個fragment,對吧。 然后這個時候我們下拉刷新又來了10條數據,我們應該播放的是新來的這10條數據的第一條。于是你等待接口返回 以后把新來的10條數據插在了我們的數據源這個數組的 頭部。 然后調用了notifyDataSetChanged這個方法。 如果你沒有重寫getItemPosition的方法的話,這個方法默認返回POSITION_UNCHANGED,這是fragmentStatePagerAdapter就認為 我這個界面不需要重繪。所以你還是在不停的播放老的視頻。 有人可能會問,我們一直加載更多的話為什么不會出現這種情況?
比方說現在的加載更多其實都是預加載,比如我們一頁是返回10條數據,當我們滑到第5條數據的時候 我們可能就會自動請求下一頁數據了。所以我們不停的滑動viewpager往后面滑,因為position在不停的變化,所以是不斷的有新的fragment進來的。 所以不管getItemPosition 的值如何變化,針對此種情況我們都會刷新界面的。
但是對于下拉刷新這種情況就不行,因為我們默認加載的是第一條數據,我們內存里面已經有了這一條數據了,對于position 位置為0的fragment來說,他已經在內存里了,等我們下拉刷新來了新數據以后,雖然我們調用了notifyDataSetChanged方法, 但是我們發現這個位置為0的fragment 內存里已經有了啊,getItemPosition又返回了POSITION_UNCHANGED,那我就不重繪了, 這就是一個容易出bug的地方。
4、既然如此我們getItemPosition固定返回POSITION_NONE行不行? 答案是不行的,固定返回POSITION_NONE這個值,雖然可以解決下拉刷新 界面不刷新的問題,但是會引發新的問題。 主要有2:
第一,固定返回POSITION_NONE 意味著每次notifyDataSetChanged被調用的時候,我們內存里存在的三個fragment都要重新繪制這樣的成本太大,低端手機明顯會卡,android大部分視頻播放都是軟解碼方案,這樣的性能不行。
第二:還是上面的預加載,比方說我們第一頁返回了10條數據,當我們滑到第五條數據的時候,我們預加載預先請求了第二頁的時候然后第二頁的數據回來以后 我們調用了notifyDataSetChanged,注意這個時候我們可能第五條數據對應的視頻我們還沒看完呢,比如這條短視頻我們才看到第六秒,結果整個界面突然重繪了,直接又重新從第一秒開始播放。。這個體驗明顯不可接受。
所以我們要做的就是在需要的時候返回POSITION_NONE不需要的時候返回 POSITION_UNCHANGED ,具體的邏輯可以根據你們自己的業務進行相應的調整。
比方說我們可以判斷一下,如果源數據也就是mData里面的id和正在播放的fragmetn里面的id相等話,我們就判定不需要刷新界面否則不相等,就刷一下,剛好對應加載更多和下拉刷新的2個場景。
5、如何定位內存泄漏的問題? 對于播放器來說,初次接觸的團隊如果沒有經驗,即使有b站開源播放器的幫助也會發生內存泄漏的問題,比方說我們 繪制一個播放界面,總免不了要畫進度條,要展示倒計時,textview默認的跑馬燈效果那么差,說不定還要自己寫個自定義view來完成跑馬燈的特效,這些都免不了使用線程,handler,timer等等容易發生內存泄漏的東西。所以當不停的滑動的時候, 如果被滑走的fragment沒有及時被釋放掉,那上線就肯定會發生oom的問題。對于android studio 3.0或者以上的版本來說:
嗯,既然mat都能讀了,剩下的就不啰嗦了,網上一搜一大堆。
6、如何根據index 取對應的fragment? 這個也是比較小眾的一個知識點,對于fragmentStatePagerAdapter來說,我們知道除了當前在使用的fragment,我們 還有這個fragment前后2個fragment,對于滑動操作來說,我們至少要完成 滑動到下一個fragmetn 要停止前面一個fragment 的視頻播放和動畫播放等等。 所以根據index 來取fragment對象就變的十分重要。
這里給出反射的實現:
public static Fragment getIndexFragment(FragmentStatePagerAdapter fragmentStatePagerAdapter, int index) { try { Field privateArrayList = FragmentStatePagerAdapter.class.getDeclaredField("mFragments"); privateArrayList.setAccessible(true); ArrayList mFragments = (ArrayList) privateArrayList.get(fragmentStatePagerAdapter); return mFragments.size() > 0 ? mFragments.get(index) : null; } catch (NoSuchFieldException e) { } catch (IllegalAccessException e) { } return null; }同為Android開發的朋友,歡迎各位關注轉發哦!
總結
以上是生活随笔為你收集整理的如何让fragment刷新界面_快速实现android版抖音主界面的心得的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 输出整形变量语句_Python合集之Py
- 下一篇: 多线程 调用 axis 报错_java笔