下面这个界面在日常开发中简直太常见不过了,viewpager+fragment组合出来的效果!
- <android.support.design.widget.TabLayout
- android:id="@+id/tab_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="#EF8D11"
- app:tabIndicatorColor="#EF4A11"
- app:tabMode="scrollable"
- app:tabSelectedTextColor="#FFFFFF"
- app:tabTextAppearance="@style/MyTabLayoutTextAppearance"
- app:tabTextColor="#FFFFFF" />
- <android.support.v4.view.ViewPager
- android:id="@+id/view_pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
属性说明:android:background="#EF8D11"
背景色app:tabIndicatorColor="#EF4A11"
tab文字下方的那条线的颜色app:tabMode="scrollable"
如果tab过多超出屏幕宽度可以水平滚动app:tabSelectedTextColor="#FFFFFF"
tab被选中的时候文字的颜色app:tabTextColor="#FFFFFF"
tab未被选中时文字的颜色app:tabTextAppearance="@style/MyTabLayoutTextAppearance"
自定义字体大小(一般使用默认即可)
1 2 3 | <style name="MyTabLayoutTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse">
<item name="android:textSize">12sp</item>
</style>
|
java 代码
- private void initView(View view) {
- mTablayout = (TabLayout) view.findViewById(R.id.tab_layout);
- //mTablayout.setTabMode(TabLayout.MODE_SCROLLABLE);//挤在一起显示
- viewpager = (ViewPager) view.findViewById(R.id.viewpager);
- setupViewPager(viewpager);
- mTablayout.addTab(mTablayout.newTab().setText("头条"));
- mTablayout.addTab(mTablayout.newTab().setText("NBA"));
- mTablayout.addTab(mTablayout.newTab().setText("汽车"));
- mTablayout.addTab(mTablayout.newTab().setText("笑话"));
- mTablayout.setupWithViewPager(viewpager);
- }
- private void setupViewPager(ViewPager viewpager) {
- MyPagerAdapter adapter=new MyPagerAdapter(getChildFragmentManager());
- adapter.addFragment(FirstListFragment.newInstance(ONE),"头条");
- adapter.addFragment(FirstListFragment.newInstance(TWO),"NBA");
- adapter.addFragment(FirstListFragment.newInstance(THREE),"汽车");
- adapter.addFragment(FirstListFragment.newInstance(FOUR),"笑话");
- viewpager.setAdapter(adapter);
- }
- public static class MyPagerAdapter extends FragmentPagerAdapter{
- private final List<Fragment> mFragment=new ArrayList<Fragment>();
- private final List<String> mFragmentTitle=new ArrayList<String>();
- public void addFragment(Fragment fragment,String title){
- mFragment.add(fragment);
- mFragmentTitle.add(title);
- }
- public MyPagerAdapter(FragmentManager fm) {
- super(fm);
- }
- @Override
- public Fragment getItem(int position) {
- return mFragment.get(position);
- }
- @Override
- public int getCount() {
- return mFragment.size();
- }
- @Override
- public CharSequence getPageTitle(int position) {
- return mFragmentTitle.get(position);
- }
- }
懒加载定义
Fragment的UI界面对用户可见的时候才加载数据。
怎么判断什么是否对用户可见呢?
- public void setUserVisibleHint(boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- if (getUserVisibleHint()) {
- //可见
- } else {
- //不可见
- }
- }
注意:fragment的缓加载,优先于oncreate方法执行,且每次切换fragment都会执行此方法!
代码
为了方便,封装一个基类 LazyLoadFragment,提供一个 loadData() 方法供调用去加载数据
- public abstract class LazyLoadFragment extends Fragment {
- /**
- * 控件是否初始化完成
- */
- private boolean isViewCreated;
- /**
- * 数据是否已加载完毕
- */
- private boolean isLoadDataCompleted;
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(getLayout(), container, false);
- initViews(view);
- isViewCreated = true;
- return view;
- }
- public abstract int getLayout();
- public abstract void initViews(View view);
- @Override
- public void setUserVisibleHint(boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- if (isVisibleToUser && isViewCreated && !isLoadDataCompleted) {
- isLoadDataCompleted = true;
- loadData();
- }
- }
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (getUserVisibleHint()) {
- isLoadDataCompleted = true;
- loadData();
- }
- }
- /**
- * 子类实现加载数据的方法
- */
- public abstract void loadData();
为什么 loadData()
会在两个地方执行?在 setUserVisibleHint 方法里执行我还能理解,为什么 onActivityCreated 也要执行呢?
因为,ViewPager 默认显示第一页,第一页肯定要先加载数据,而且 setUserVisibleHint 的执行顺序又是在 onCreatView 之前,同时 onCreatView 需要初始化界面和修改 isViewCreated 的值。所以就需要在 onActivityCreated 里执行一次。