Fragment基本介紹(三) ----之Tablayout+ViewPage+Fragment
一,兩種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;
}
}