ViewPager与Fragment、TabLayout的搭配使用

KaelLi 2019年3月7日13:17:17
评论
4,6421

ViewPager+Fragment的组合是开发中比较常见的,而且这也是Google官方推荐的组合,因为Fragment有着完备的生命周期,所以能适合大多数需要使用ViewPager的场景。

ViewPager+Fragment的使用场景

最常见的,比如用户量最大的今日头条、网易新闻等,其主页面就是很明显的ViewPager跟众多的Fragment搭配,顶部再来一个风格各异的指示器。用户可以很随意的进行左右滑动的操作。总体来说,需要大量页面并列滑动的时候,ViewPager+Fragment就是非常好的选择。

 

ViewPager与Fragment、TabLayout的搭配使用

网易新闻主页面,可以用ViewPager+Fragment的组合实现

ViewPager+Fragment的代码实现

先来一个最简单的Fragment的代码,布局就不展示了,里面只有一个居中的TextView,Java代码也十分简单,就是把TextView的内容设置为其在ViewPager中的位置:

public class VPFragment extends Fragment {
    private TextView mTextView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_viewpager, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        mTextView = view.findViewById(R.id.mTextView);
        mTextView.setText("这是第" + getArguments().getInt("position") + "个Fragment");
    }
}

我们知道,ViewPager是需要绑定一个PagerAdapter的,当然你依然可以自己手写,但是实际上Google已经给我们提供好了:FragmentPagerAdapter和FragmentStatePagerAdapter这2个PagerAdapter的实现,我们只需要从中选择一个使用即可。在Fragment数量不是特别大的时候,使用FragmentPagerAdapter足矣。由于FragmentPagerAdapter内部已经实现好了instantiateItem和destroyItem方法,所以我们只需要实现一个传入FragmentManager参数的构造方法和getItem、getCount这2个方法即可:

public class TestFragmentAdapter extends FragmentPagerAdapter {
    public TestFragmentAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment = new VPFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("position", i);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public int getCount() {
        return 5;
    }
}

然后把ViewPager与Adapter进行绑定:

vpTest.setAdapter(new TestFragmentAdapter(getSupportFragmentManager()));

效果嘛,因为我这里给出的Fragment实在是太过简陋,所以大家看到滑动的效果就可以了:

ViewPager与Fragment、TabLayout的搭配使用

最简陋的ViewPager+Fragment的运行效果

当然了这只是最简单的运用了。实际上你可以把Fragment写得更复杂一些,而且数量上也没有什么限制,设置成int的最大值都可以,只要你能处理好每个位置的Fragment实现就行。

ViewPager+Fragment+TabLayout的组合使用

TabLayout是Google在Support:Design包里为我们提供的一个指示器,它继承自HorizontalScrollView,所以实际上它是一个可以横向滑动的控件。很多时候,我们都会用它来跟ViewPager搭配,而ViewPager+Fragment+TabLayout也是开发中十分经典常用的组合,大部分情况下能够满足相应的产品需求。

想要给ViewPager配一个相应的TabLayout,需要的代码很少,因为Google其实内部给TabLayout做了很多的工作,开发者使用起来是非常方便的。记住,别忘了在build.gradle中添加com.android.support:design的依赖。

先在布局文件里声明一下,一般情况下都是直接放在ViewPager上方的:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        app:layout_constraintTop_toTopOf="parent"/>
    <android.support.v4.view.ViewPager
        android:id="@+id/vpTest"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@+id/tabLayout"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

然后把TabLayout与ViewPager进行绑定:

tabLayout.setupWithViewPager(vpTest);

接下来需要把PagerAdapter在之前实现的基础上,再额外覆盖一个getPageTitle方法,这个方法就决定了TabLayout在相应位置应该怎么显示标题:

public class TestFragmentAdapter extends FragmentPagerAdapter {
    public TestFragmentAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment = new VPFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("position", i);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public int getCount() {
        return 5;
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return "标题" + position;
    }
}

再来看一下运行效果:

ViewPager与Fragment、TabLayout的搭配使用

简单的ViewPager+Fragment+TabLayout运行效果

当然了,TabLayout实际上还能有别的一些设置,不过Google为我们提供的原生TabLayout能做的调整不多,只能满足大多数时候的一般需求。如果对指示器的产品需求比较复杂,可能就需要我们自定义实现或者使用一些开源库了。

总结

ViewPager+Fragment+TabLayout的组合简单好用,而且如果再配合CoordinatorLayout更是能实现非常好的体验。当然了,很多人现在都喜欢用RecyclerView去实现ViewPager的效果了,原因是RecyclerView更新、更强大,而且目前Google新推的AndroidX(一个新库,可以大致理解为Support库的升级版)里的ViewPager2,内部也是由RecyclerView实现的,喜欢尝鲜的朋友可以去了解、使用。

需要注意的是,这里需要使用的Fragment是android.support.v4.app下的Fragment,而不是android.app下的Fragment。原因嘛,直接去看FragmentPagerAdapter或FragmentStatePagerAdapter就知道了,里面的Fragment就是android.support.v4.app.Fragment。另外,目前android.app.Fragment已经被加上了@Deprecated注解了,它已经过时了,Google已经不推荐使用了,原因是v4下的Fragment现在支持Lifecycle了,更好用,而且总维持2个Fragment类也会让开发者混淆吧。

KaelLi
  • 本文由 发表于 2019年3月7日13:17:17
  • 转载请务必保留本文链接:https://www.kaelli.com/35.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: