Android仿今日頭條多個fragment懶加載的實現(xiàn)
前言
最近有時間,所以我又雙叒叕推新一篇文章了,fragment懶加載實現(xiàn)雖然是個小模塊,但做過的人都有體會,通常并不會輕易就成功了的,讓你輾轉反側,徹夜難眠,綿綿無絕期。我就按照今日頭條的樣式做了一個懶加載功能。文章到一半會解釋大家可能遇到的不加載數(shù)據(jù)了的坑,先不劇透。
Fragment的生命周期回顧
這里是今日頭條效果:
自制效果,有圖有真相:
實現(xiàn)思路:
使用Fragment類自帶方法setUserVisibleHint()判斷當前fragment是否對用戶可見,根據(jù)回調(diào)的isVisibleToUser參數(shù)來進行相關的邏輯判斷。重寫該方法,創(chuàng)建變量isVisible拿到是否可見標志。
但是直接根據(jù)isVisible判斷就加載數(shù)據(jù),可能onCreateView()方法并未執(zhí)行完畢,此時就會出現(xiàn)NullPointerException空指針異常。所以就需要滿足控件初始化完成,用戶可見,才能加載數(shù)據(jù)。
LazyloadFragment懶加載fragment實現(xiàn):
public abstract class LazyloadFragment extends Fragment { protected View rootView; private boolean isInitView = false; private boolean isVisible = false; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { rootView = inflater.inflate(setContentView(), container, false); init(); isInitView = true; isCanLoadData(); return rootView; } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); //isVisibleToUser這個boolean值表示:該Fragment的UI 用戶是否可見,獲取該標志記錄下來 if(isVisibleToUser){ isVisible = true; isCanLoadData(); }else{ isVisible = false; } } private void isCanLoadData(){ //所以條件是view初始化完成并且對用戶可見 if(isInitView && isVisible ){ lazyLoad(); //防止重復加載數(shù)據(jù) isInitView = false; isVisible = false; } } /** * 加載頁面布局文件 * @return */ protected abstract int setContentView(); /** * 讓布局中的view與fragment中的變量建立起映射 */ protected abstract void init(); /** * 加載要顯示的數(shù)據(jù) */ protected abstract void lazyLoad(); }
子fragment加載數(shù)據(jù):
public class PageFragment extends LazyloadFragment implements XRecyclerView.LoadingListener { private CommonAdapter<String> adapter; private ArrayList<String> datas = new ArrayList<>(); private XRecyclerView recyclerView; private Handler handler = new Handler(); @Override public int setContentView() { return R.layout.fragment_page; } @Override public void init() { recyclerView = rootView.findViewById(R.id.recyclerview); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); adapter = new CommonAdapter<String>(getActivity(),R.layout.item,datas) { @Override protected void convert(ViewHolder holder, String s, int position) { } }; recyclerView.setAdapter(adapter); recyclerView.setPullRefreshEnabled(true); recyclerView.setLoadingListener(this); } @Override public void lazyLoad() { recyclerView.refresh(); } @Override public void onRefresh() { handler.postDelayed(new Runnable() { @Override public void run() { recyclerView.refreshComplete(); for(int i=0;i<10;i++){ datas.add(""); } adapter.notifyDataSetChanged(); } },500); } @Override public void onLoadMore() { } }
最后Mainactivity代碼:
public class MainActivity extends AppCompatActivity { private TabLayout tabLayout; private String[] topics = new String[]{"推薦","熱點","北京","視頻","社會","圖片"}; private ViewPager viewPager; private ArrayList<Fragment> fragments = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); init(); } private void init() { viewPager = (ViewPager) findViewById(R.id.viewpager); tabLayout = (TabLayout) findViewById(R.id.tablayout); viewPager.setOffscreenPageLimit(3); for(int i=0;i<topics.length;i++){ tabLayout.addTab(tabLayout.newTab()); fragments.add(new PageFragment()); } viewPager.setAdapter(new FmPagerAdapter(fragments,getSupportFragmentManager())); tabLayout.setupWithViewPager(viewPager); for (int j = 0; j < topics.length; j++) { tabLayout.getTabAt(j).setText(topics[j]); } } }
坑來了
大家千篇一律地說用setUserVisibleHint()方法就可以了,但是沒有說這個問題。是不是用了Lazyloadfragment不加載數(shù)據(jù)了?因為你用的是Viewpager用的是PagerAdapter,用pageradapter,打斷點調(diào)試,根本就沒有調(diào)用setUserVisibleHint(),所以isVisible還是false,不執(zhí)行l(wèi)azyload方法。需要用FragmentPagerAdapter顯示調(diào)用setUserVisibleHint()。
換上FragmentPagerAdapter后調(diào)試,調(diào)用setUserVisibleHint,isVisible為ture了。
總結
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
Android ormlite更改數(shù)據(jù)庫默認位置
本文主要介紹Android ormlite,這里提供實例代碼并詳細說明了 ormlite更改數(shù)據(jù)庫默認位置,有需要的朋友可以參考下2016-07-07使用RoundedBitmapDrawable生成圓角圖片的方法
由于RoundedBitmapDrawable類沒有直接提供生成圓形圖片的方法,所以生成圓形圖片首先需要對原始圖片進行裁剪,將圖片裁剪成正方形,最后再生成圓形圖片,具體實現(xiàn)方法,可以參考下本文2016-09-09listView的item中有checkbox,導致setOnItemClick失效的原因及解決辦法
這篇文章主要介紹了listView的item中有checkbox,導致setOnItemClick失效的原因及解決辦法,需要的朋友可以參考下2017-01-01Eclipse NDK遷移到Android Studio的方法示例
本篇文章主要介紹了Eclipse NDK遷移到Android Studio的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03Android開發(fā)中使用achartengine繪制各種圖表的方法
這篇文章主要介紹了Android開發(fā)中使用achartengine繪制各種圖表的方法,結合具體實例形式分析了Android基于圖表生成類庫achartengine進行圖表繪制的具體步驟與相關操作技巧,需要的朋友可以參考下2017-10-10