一,两种adapter使用场景
- FragmentStatePagerAdapter和FragmentPagerAdapter
- 1,两种Adapter特点分析
a)fragmentPagerAdapter带有缓存,内存开销大,响应速度很快
b)FragmentStatePagerAdapter没有缓存,内存开销小,响应速度稍慢。
c)FragmentStatePagerAdapter如果想用缓存,需要自己动手写。
- 2,使用场景分析
a)FragmentPagerAdapter缓存所有页面,因此适合fragment页面较少(20以内),并且单个页面开销小(没有webview、surfaceView重量组件,或大量图片)
d)FragmentStatePagerAdapter相反,适合内存压力很大的场景。可以自己控制缓存逻辑。
e)实战时根据需求(用户行为)选择。比如证券APP不需要做缓存,而谷歌市场缓存时间应该在1天以内。
二,ViewPager的setOffscreenPageLimit()
viewPager.setOffscreenPageLimit(1);
- 1,setOffscreenPageLimit 默认值是1,
默认加载3个页面.当前页面和左右各一个页面
但如果加载的是第1页,就只会预加载第2页,总共是2页
如果滑动到第2页,就会预加载第1页和第3页,总共是3页
二层意思
一是 ViewPager 会预加载几页;
二是 ViewPager 会缓存 2*n+1 页(n为设置的值).
- 2.ViewPager 中的 fragment 是否执行 onViewDestory 或者 onDestory 与 setOffscreenPageLimit 方法设置的值有关.
- 3,懒加载:setOffscreenPageLimit(0)
- 但是,修改后就会有一个麻烦的地方,因为移动时不会预先加载下一个界面的关系,所以会看到一片黑色的背景.
如果当前加载的页面有多个请求, 又预加载下个页面的请求, 导致多个任务等待, 这会影响到当前页面的请求速度. 所以合理的做法是当页面对于用户可见时再去请求数据.
- 4,不做懒加载(预加载)
如果当前页面和隔壁页面网络请求单一,就可以使用预加载,这样用户体验很好
三,代码实现
(一)效果图
(二),布局展示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/home_tab"
app:tabIndicatorHeight="0dp"
app:tabMode="scrollable"
app:tabBackground="@color/freecolor_white"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/home_page"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</LinearLayout>
(三)父Fragment中的代码
1,Fragment嵌套,要使用getChildFragmentManager.
2,背景图片需要用到自定义tab.setCustomView
package laobi.com.home;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TextView;
import laobi.com.core.BaseFragment;
import laobi.com.home.adapter.MainFragmentPagerAdapter;
/**
* Created by biyaobing on 2018/3/1.
*/
public class HomeFragment extends BaseFragment {
private TabLayout mHome_tab;
private ViewPager mHome_page;
private String [] titles = {"标题一","标题二","标题三","标题四","标题五","标题六"};
private View mView;
@Override
protected View initView() {
mView = View.inflate(mContext, R.layout.fragment_home, null);
return mView;
}
@Override
protected void init() {
intiUI(mView);
}
private void intiUI(View view) {
mHome_tab = (TabLayout) view.findViewById(R.id.home_tab);
mHome_page = (ViewPager) view.findViewById(R.id.home_page);
mHome_page.setAdapter(new MainFragmentPagerAdapter(getChildFragmentManager(),titles));//getSupportFragmentManager
mHome_page.setOffscreenPageLimit(2);//设置预加载的页面数量,设置0无效,因为源码最低值是1
//方法的调用必须在viewpager设置完适配器后调用,如果在设置适配器之前调用会抛异常
mHome_tab.setupWithViewPager(mHome_page);
setCustomeTab();
initPageListener();
}
private void setCustomeTab() {
for (int i = 0; i < titles.length; i++) {
TabLayout.Tab tab = mHome_tab.getTabAt(i);//获得每一个tab
tab.setCustomView(R.layout.my_tablayout);//给每一个tab设置view
TextView mTv_custome = (TextView) tab.getCustomView().findViewById(R.id.tv_title);
mTv_custome.setText(titles[i]);//设置tab上的文字
if (i == 0) {
setChecked(mTv_custome);
}
}
}
private void setChecked(TextView mTv_custome) {
mTv_custome.setSelected(true);
mTv_custome.setBackgroundResource(R.drawable.bg);
mTv_custome.setTextColor(getResources().getColor(R.color.freecolor_white));
}
private void initPageListener() {
mHome_tab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
TextView textView = (TextView) tab.getCustomView().findViewById(R.id.tv_title);
setChecked(textView);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
TextView textView = (TextView) tab.getCustomView().findViewById(R.id.tv_title);
textView.setBackgroundColor(getResources().getColor(R.color.freecolor_white));
textView.setTextColor(getResources().getColor(R.color.tv_black));
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}
(四)FragmentPagerAdapter种的代码
public class MainFragmentPagerAdapter extends FragmentPagerAdapter {
private final String[] mTitles;
/**
* 告诉adapter每个页面的标题
* @param position
* @return
*/
@Override
public CharSequence getPageTitle(int position) {
return mTitles[position];
}
public MainFragmentPagerAdapter(FragmentManager fm, String[] titles) {
super(fm);
this.mTitles = titles;
}
@Override
public Fragment getItem(int position) {
Fragment fragment;
switch (position){
case 0:
Bundle bundle = new Bundle();
bundle.putString("test","测试首页11成功");
fragment = Fragment1_Home.newInstance(bundle);
break;
case 1:
Bundle bundle2 = new Bundle();
bundle2.putString("test","测试2222成功");
fragment = Fragment2_Home.newInstance(bundle2);
break;
case 2:
Bundle bundle3= new Bundle();
bundle3.putString("test","测试333成功");
fragment = Fragment3_Home.newInstance(bundle3);
break;
case 3:
Bundle bundle4= new Bundle();
bundle4.putString("test","测试444成功");
fragment = Fragment3_Home.newInstance(bundle4);
break;
case 4:
Bundle bundle5= new Bundle();
bundle5.putString("test","测试555成功");
fragment = Fragment3_Home.newInstance(bundle5);
break;
case 5:
Bundle bundle6= new Bundle();
bundle6.putString("test","测试666成功");
fragment = Fragment3_Home.newInstance(bundle6);
break;
default:
Bundle bundle1 = new Bundle();
bundle1.putString("test","测试首页11成功");
fragment = Fragment1_Home.newInstance(bundle1);
}
return fragment;
}
@Override
public int getCount() {
return mTitles.length;
}
}