第7天ViewPagerViewPager+Fragment+TabLayout新闻头部标题导航(*****)
ViewPager
一.效果
二.思路:1个ViewPager+5个Fragment+1个FragmentPagerAdapter+TabLayout
1.容器:ViewPager
2.数据:ArrayList<Fragment ArrayList<String 标题
3.适配器:FragmentViewPager
4.TabLayout:需要导入依赖
重写的方法:
(1)getCount():返回数据源的总数量
(2)getItem():
(3)getPageTitle():返回标题
三.代码
(1)导入依赖:implementation ‘com.android.support:design:30.0.0’
(2)布局activity_main.xml:ViewPager+TabLayout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<!--tabLayout依赖-->
<android.support.design.widget.TabLayout
app:tabSelectedTextColor="#E5AF35"
app:tabTextColor="#969696"
app:tabIndicatorColor="#E5AF35"
app:tabIndicatorHeight="5dp"
app:tabMode="scrollable"
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_weight="8"
android:layout_height="0dp"
android:layout_width="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
(3)Java代码:MainActivity.java
public class MainActivity extends AppCompatActivity {
//视图
private ViewPager vp;
private TabLayout tb;
//数据
private ArrayList<Fragment> fragment_list=new ArrayList<>();
private ArrayList<String> title_list=new ArrayList<>();//标题
//适配器
private MyFragmentPagerAdapter myFragmentPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initview();
initdata();
initadpater();
//TODO tablayout和viewpager联系在一起
tb.setupWithViewPager(vp);
}
private void initadpater() {
myFragmentPagerAdapter=new MyFragmentPagerAdapter(getSupportFragmentManager(),fragment_list,title_list);
vp.setAdapter(myFragmentPagerAdapter);
}
private void initdata() {
fragment_list.add(new Fragment1());
fragment_list.add(new Fragment2());
fragment_list.add(new Fragment3());
fragment_list.add(new Fragment4());
title_list.add("我的");
title_list.add("新闻");
title_list.add("最热");
title_list.add("最强");
}
private void initview() {
vp=findViewById(R.id.vp);
tb=findViewById(R.id.tb);
}
}
(4)适配器代码:MyFragmentPagerAdapter.java
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragment_list;
private ArrayList<String> title_list;
public MyFragmentPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragment_list,ArrayList<String> titile_list) {
super(fm);
this.fragment_list=fragment_list;
this.title_list=titile_list;
}
@Override
public Fragment getItem(int i) {
return fragment_list.get(i);
}
@Override
public int getCount() {
return fragment_list.size();
}
//TODO 返回对应的标题
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return title_list.get(position);
}
}
四.提薪点:使用工厂模式创建fragment
1.工厂模式
public class FragmentFactory {
//SparseArray 稀疏数组:安卓特有的类,默认键是int类型,节省内存,性能更好
private static SparseArray<Fragment> mFragments = new SparseArray<Fragment>();
/***
* 之前创建过直接获取,没有创建过创建出来并存储到稀疏数组中
* @param position 下标
* @return
*/
public static Fragment createFragment(int position){
Fragment fragment = mFragments.get(position);
if (fragment == null) {
switch (position) {
case 0:
fragment = new OneFragment();
break;
case 1:
fragment = new TwoFragment();
break;
case 2:
fragment = new ThreeFragment();
break;
}
if (fragment != null) {
mFragments.put(position, fragment);
}
}
return fragment;
}
}
2.代码使用:使用工厂模式创建fragment
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private List<Fragment> list;
private List<String> list_title;
private MyPagerAdapter myPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.view_pager);
tabLayout = findViewById(R.id.tab);
list = new ArrayList<>();
list_title = new ArrayList<>();
//使用工厂模式
list.add(FragmentFactory.createFragment(0));
list.add(FragmentFactory.createFragment(1));
list.add(FragmentFactory.createFragment(2));
list_title.add("1");
list_title.add("2");
list_title.add("3");
myPagerAdapter = new MyPagerAdapter(getSupportFragmentManager(),list,list_title);
viewPager.setAdapter(myPagerAdapter);
//****** viewpager和tablayout连结
tabLayout.setupWithViewPager(viewPager);
}
}
五.提薪点:fragment懒加载
1.为什么要实现fragment懒加载
-
ViewPager控件有个特有的预加载机制,即默认情况下当前页面左右两侧的1个页面会被加载,以方便用户滑动切换到相邻的界面时,可以更加顺畅的显示出来.
-
通过ViewPager的setOffscreenPageLimit(int limit)可以设置预加载页面数量,当前页面相邻的limit个页面会被预加载进内存
-
缺点:预加载越多就会越卡顿累计到后面就会OOM,懒加载实现就很必要
2.什么是fragment懒加载
懒加载:其实也就是延迟加载,就是等到该页面的UI展示给用户时,再加载该页面的数据(从网络、数据库等),而不是依靠ViewPager预加载机制提前加载两三个,甚至更多页面的数据.这样可以提高所属Activity的初始化速度,也可以为用户节省流量.而这种懒加载的方式也已经/正在被诸多APP所采用.
3.代码实现
- 步骤一:两个布尔型标记来记录这两个条件的状态.只有同时满足了,才能加载数据
//Fragment的View加载完毕的标记
private boolean isViewCreated;
//Fragment对用户可见的标记
private boolean isUIVisible;
- 步骤二:改变isViewCreated标记
当onViewCreated()方法执行时,表明View已经加载完毕,此时改变isViewCreated标记为true,并调用lazyLoad()方法
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
isViewCreated = true;
lazyLoad();
}
- 步骤三:改变isUIVisible标记
当setUserVisibleHint(boolean isVisibleToUser)回调为true时,改变isUIVisible标记为true,并调用lazyLoad()方法
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
//isVisibleToUser这个boolean值表示:该Fragment的UI 用户是否可见
if (isVisibleToUser) {
isUIVisible = true;
lazyLoad();
} else {
isUIVisible = false;
}
}
- 步骤四:在lazyLoad()方法中进行双重标记判断,通过后即可进行数据加载
private void lazyLoad() {
//这里进行双重标记判断,是因为setUserVisibleHint会多次回调,并且会在onCreateView执行前回调,必须确保onCreateView加载完毕且页面可见,才加载数据
if (isViewCreated && isUIVisible) {
loadData();
//数据加载完毕,恢复标记,防止重复加载
isViewCreated = false;
isUIVisible = false;
printLog(mTextviewContent+"可见,加载数据");
}
}