下面这个界面在日常开发中简直太常见不过了,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);
}
MyPagerAdaper
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 里执行一次。