Android仿今日頭條多個(gè)fragment懶加載的實(shí)現(xiàn)
前言
最近有時(shí)間,所以我又雙叒叕推新一篇文章了,fragment懶加載實(shí)現(xiàn)雖然是個(gè)小模塊,但做過(guò)的人都有體會(huì),通常并不會(huì)輕易就成功了的,讓你輾轉(zhuǎn)反側(cè),徹夜難眠,綿綿無(wú)絕期。我就按照今日頭條的樣式做了一個(gè)懶加載功能。文章到一半會(huì)解釋大家可能遇到的不加載數(shù)據(jù)了的坑,先不劇透。
Fragment的生命周期回顧

這里是今日頭條效果:

自制效果,有圖有真相:

實(shí)現(xiàn)思路:
使用Fragment類(lèi)自帶方法setUserVisibleHint()判斷當(dāng)前fragment是否對(duì)用戶(hù)可見(jiàn),根據(jù)回調(diào)的isVisibleToUser參數(shù)來(lái)進(jìn)行相關(guān)的邏輯判斷。重寫(xiě)該方法,創(chuàng)建變量isVisible拿到是否可見(jiàn)標(biāo)志。
但是直接根據(jù)isVisible判斷就加載數(shù)據(jù),可能onCreateView()方法并未執(zhí)行完畢,此時(shí)就會(huì)出現(xiàn)NullPointerException空指針異常。所以就需要滿(mǎn)足控件初始化完成,用戶(hù)可見(jiàn),才能加載數(shù)據(jù)。

LazyloadFragment懶加載fragment實(shí)現(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這個(gè)boolean值表示:該Fragment的UI 用戶(hù)是否可見(jiàn),獲取該標(biāo)志記錄下來(lái)
if(isVisibleToUser){
isVisible = true;
isCanLoadData();
}else{
isVisible = false;
}
}
private void isCanLoadData(){
//所以條件是view初始化完成并且對(duì)用戶(hù)可見(jiàn)
if(isInitView && isVisible ){
lazyLoad();
//防止重復(fù)加載數(shù)據(jù)
isInitView = false;
isVisible = false;
}
}
/**
* 加載頁(yè)面布局文件
* @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[]{"推薦","熱點(diǎn)","北京","視頻","社會(huì)","圖片"};
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]);
}
}
}
坑來(lái)了
大家千篇一律地說(shuō)用setUserVisibleHint()方法就可以了,但是沒(méi)有說(shuō)這個(gè)問(wèn)題。是不是用了Lazyloadfragment不加載數(shù)據(jù)了?因?yàn)槟阌玫氖荲iewpager用的是PagerAdapter,用pageradapter,打斷點(diǎn)調(diào)試,根本就沒(méi)有調(diào)用setUserVisibleHint(),所以isVisible還是false,不執(zhí)行l(wèi)azyload方法。需要用FragmentPagerAdapter顯示調(diào)用setUserVisibleHint()。

換上FragmentPagerAdapter后調(diào)試,調(diào)用setUserVisibleHint,isVisible為ture了。

總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Android webview手動(dòng)校驗(yàn)https證書(shū)(by 星空武哥)
有些時(shí)候由于Android系統(tǒng)的bug或者其他的原因,導(dǎo)致我們的webview不能驗(yàn)證通過(guò)我們的https證書(shū),最明顯的例子就是華為手機(jī)mate7升級(jí)到Android7.0后,手機(jī)有些網(wǎng)站打不開(kāi)了,而更新了webview的補(bǔ)丁后就沒(méi)問(wèn)題了2017-09-09
Android編程圖片加載類(lèi)ImageLoader定義與用法實(shí)例分析
這篇文章主要介紹了Android編程圖片加載類(lèi)ImageLoader定義與用法,結(jié)合實(shí)例形式分析了Android圖片加載類(lèi)ImageLoader的功能、定義、使用方法及相關(guān)操作注意事項(xiàng),代碼中備有較為詳盡的注釋便于理解,需要的朋友可以參考下2017-12-12
Android實(shí)現(xiàn)類(lèi)似360,QQ管家那樣的懸浮窗
用到的就是WindowManager以及WindowManager.LayoutParams,對(duì)這個(gè)LayoutParams做文章,當(dāng)設(shè)置為屬性后,然后,創(chuàng)建一個(gè)View,將這個(gè)View添加到WindowManager中就行2013-06-06
Android 幾種屏幕間跳轉(zhuǎn)的跳轉(zhuǎn)Intent Bundle
這篇文章主要介紹了Android 幾種屏幕間跳轉(zhuǎn)的跳轉(zhuǎn)Intent Bundle,有需要的朋友可以參考一下2013-12-12
ActivityManagerService之Service啟動(dòng)過(guò)程解析
這篇文章主要為大家介紹了ActivityManagerService之Service啟動(dòng)過(guò)程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
100行Android代碼輕松實(shí)現(xiàn)帶動(dòng)畫(huà)柱狀圖
這篇文章主要教大家通過(guò)100行Android代碼輕松實(shí)現(xiàn)帶動(dòng)畫(huà)柱狀圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android開(kāi)發(fā)Jetpack組件DataBinding用例詳解
這篇文章主要為大家介紹了Android開(kāi)發(fā)Jetpack組件DataBinding的使案用例詳解說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
Android學(xué)習(xí)筆記之藍(lán)牙功能
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)筆記之藍(lán)牙功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
android View 繪制完成監(jiān)聽(tīng)的實(shí)現(xiàn)方法
今天小編就為大家分享一篇android View 繪制完成監(jiān)聽(tīng)的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
Ionic2創(chuàng)建App啟動(dòng)頁(yè)左右滑動(dòng)歡迎界面
使用Ionic2創(chuàng)建應(yīng)用非常簡(jiǎn)單,只需在V1的命令后跟上--v2即可.這篇文章主要介紹了Ionic2創(chuàng)建App啟動(dòng)頁(yè)左右滑動(dòng)歡迎界面的相關(guān)資料,需要的朋友可以參考下2016-10-10

