关于酷安首页Fragment的尝试实现
需求List
ViewPage承载多个Fragment
每个Fragment都以LazyFragmeng呈现
Fragment首次可见时出现数据加载页面
Fragmeng再次可见时保留内容
Fragment中内容全部为RecyclerView
ViewPage承载多个Fragment
首先酷安的首页是很典型的TabLayout + FragmentViewPage实现Fragment
所以这里可以使用最典型的通用方案
首先是布局代码 非常简朴的TabLayout + ViewPage
1234567891011121314
<android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="48dp" app:layout_scrollFlags="snap" app:tabIndicatorColor="#ffff8c" app:tabSelectedTextColor="#645332" app:tabTextColor="#000000" /> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="48dp"/>
之后定义一个dataClass 将Fragment和它的Title绑定
1234
data class ( val title: String, val fragment: Fragment)
在MainActivity中调用initTabBar方法初始化数据
12345678910111213141516171819202122232425
private fun initTabBar() { val fragmentTabs = ArrayList<FragmentTab>() fragmentTabs.add(FragmentTab("title1",BlankFragment())) fragmentTabs.add(FragmentTab("title2",BlankFragment2())) fragmentTabs.add(FragmentTab("title3",BlankFragment3())) val adapter = object : FragmentPagerAdapter(supportFragmentManager) { override fun getItem(i: Int): Fragment { return fragmentTabs[i].fragment } override fun getCount(): Int { return fragmentTabs.size } override fun getPageTitle(position: Int): CharSequence? { return fragmentTabs[position].title } } viewPager.adapter = adapter tab_layout.setupWithViewPager(viewPager, true) tab_layout.getTabAt(1)!!.select() }
每个Fragment都以LazyFragmeng呈现
LazyFragment : ViewPager + Fragment 实现左右切换的页面,默认会加载当前Fragment和相邻的Fragment数据,为了更好的用户体验,最好是切到当前Fragment再加载数据,这样会为用户节约很多流量,另外ViewPager的setOffscreenPageLimit(n)可以设置缓存页面,当前页面的相邻n各页面都会被缓存。做到当前Fragment加载数据需要重写setUserVisibleHint方法,一般网上Fragment 懒加载实现方法都是如下这样的:
123456大专栏 关于酷安首页Fragment的尝试实现>789101112131415161718192021222324 > protected boolean isVisible;> > public void setUserVisibleHint(boolean isVisibleToUser) {> super.setUserVisibleHint(isVisibleToUser);> if (getUserVisibleHint()) {> isVisible = true;> onVisible();> } else {> isVisible = false;> onInvisible();> }> }> protected void onVisible() {> lazyLoad();> }> protected void lazyLoad() {> if (!isVisible) {> return;> }> > }> protected void onInvisible() {> }>
对,这样确实实现了懒加载,然后实际开发中,请求数据完毕,会绑定RecyclerView数据源,结果会发现报空指针异常,原来是setUserVisibleHint方法会比onCreateView先走,RecyclerView肯定是null,基于此,我们可以再添加一个标志位,判断初始化是否完成,然后再去请求数据,这样就不会有问题了,完整代码如下:
1234567891011121314151617181920212223242526272829303132333435363738394041 > public class LazyFragmeng extends Fragment {> > private boolean isPrepared;> > private boolean isVisible;> > public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {> return inflater.inflate(R.layout.weiyan, container, false);> }> > public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {> super.onViewCreated(view, savedInstanceState);> isPrepared = true;> lazyLoad();> }> > public void setUserVisibleHint(boolean isVisibleToUser) {> super.setUserVisibleHint(isVisibleToUser);> //懒加载> if (getUserVisibleHint()) {> isVisible = true;> onVisible();> } else {> isVisible = false;> onInvisible();> }> }> protected void onVisible() {> lazyLoad();> }> protected void lazyLoad() {> if (!isVisible || !isPrepared) {> return;> }> > }> protected void onInvisible() {> }> }> >