欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android ViewPager、ViewPager2的基本使用详解及区别

程序员文章站 2022-03-29 23:09:17
这里写自定义目录标题欢迎使用Markdown编辑器ViewPager2 + ItemViewViewPager2 + Fragment合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器你好! 这是你第一次使用...

本篇Blog记录ViewPager和ViewPager2

嵌套Fragment的效果图

Android ViewPager、ViewPager2的基本使用详解及区别

ViewPager的使用

关于ViewPager的使用已经很常见了,这里在复习一下吧。配合TabLayout

  1. 布局文件

    在ViewPager的布局中允许存在子view,我们可以把TabLayout作为ViewPager的子View写在ViewPager内部,也可以并列。

		<androidx.viewpager.widget.ViewPager
            android:id="@+id/vp_merchant_main"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintVertical_weight="1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/banner_merchant_main"
            app:layout_constraintBottom_toBottomOf="parent">

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tab_layout_merchant_main"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                app:tabGravity="center"
                app:tabIndicatorColor="@color/tabLayoutIndicatorStartColor"
                app:tabSelectedTextColor="@color/textColor"
                app:tabTextAppearance="@android:style/TextAppearance.Holo"
                app:tabTextColor="@color/defaultTextColor" />
        </androidx.viewpager.widget.ViewPager>
  1. Java代码

    代码中我们只需要把Fragment和Titles传入Adapter,然后再设置到ViewPager上就可以了。

    我们也可以调用Tablayout的setupWithViewPager()方法使TabLayout和ViewPager进行绑定

		// ViewPager处理
        ArrayList<Fragment> fragmentList = new ArrayList<>();
        fragmentList.add(new AllProductFragment(this));
        fragmentList.add(new EvaluationFragment(this));
        String[] fragmentTitles = {"商品", "评价"};
        ViewPagerScrollAdapter scrollAdapter = new ViewPagerScrollAdapter(getSupportFragmentManager());
        scrollAdapter.setFragmentTitles(fragmentTitles);
        scrollAdapter.setMenuFragmentList(fragmentList);
        merchantMainBinding.vpMerchantMain.setAdapter(scrollAdapter);
  1. Adapter

    注意:ViewPager的Adapter需要继承FragmentStatePagerAdapter

public class ViewPagerScrollAdapter extends FragmentStatePagerAdapter {
    private ArrayList<Fragment> menuFragmentList;
    private String [] fragmentTitles;

    public ViewPagerScrollAdapter(@NonNull FragmentManager fm) {
        super(fm);
    }

    public ViewPagerScrollAdapter(@NonNull FragmentManager fm, int behavior) {
        super(fm, behavior);
    }

    public void setFragmentTitles(String[] fragmentTitles) {
        this.fragmentTitles = fragmentTitles;
    }

    public void setMenuFragmentList(ArrayList<Fragment> menuFragmentList) {
        this.menuFragmentList = menuFragmentList;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return menuFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return menuFragmentList.size();
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return fragmentTitles[position];
    }
}

到这儿关于ViewPager的基本使用就完成了。下面是ViewPager2的使用

ViewPager2的使用

关于ViewPager2嵌套Fragment的使用很简单。

  1. 布局文件

    在布局中ViewPager2的使用是不允许有自View的,我们这里仍然配合TabLayout使用。

		<com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout_group"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:orientation="horizontal"
            app:layout_constraintBottom_toTopOf="@id/vp_group_page"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_home_group_list_title"
            app:tabIndicatorColor="@color/white"
            app:tabIndicatorFullWidth="false"
            app:tabSelectedTextColor="@color/bottomTextColor"
            app:tabTextAppearance="@android:style/TextAppearance.Holo"
            app:tabTextColor="@color/defaultTextViewColor" />

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/vp_group_page"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="horizontal"
            android:paddingTop="6dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tab_layout_group"
            app:layout_constraintVertical_weight="1" />
  1. 创建Adapter

    Adapter需要继承FragmentStateAdapter

public class LiveViewPagerAdapter extends FragmentStateAdapter {
    private ArrayList<Fragment> fragmentList;

    public LiveViewPagerAdapter(@NonNull Fragment fragment) {
        super(fragment);
    }

    public LiveViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    public LiveViewPagerAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
        super(fragmentManager, lifecycle);
    }

    public void setFragmentList(ArrayList<Fragment> fragmentList) {
        this.fragmentList = fragmentList;
    }

    ......
}
  1. 重写createFragment和getItemCount方法

    需要在Adapter中重写这两个方法

	@NonNull
    @Override
    public Fragment createFragment(int position) {
    	// 返回Fragment
        return fragmentList.get(position);
    }

    @Override
    public int getItemCount() {
    	// 获取Fragment数量
        return fragmentList.size();
    }
  1. Activity / Fragment 中的使用

    这里以Fragment为例,在父Fragment中使用,在initData方法中设置Fragment List,在initView中setAdapter。

    和我们在RecyclerView中设置Adapter和数据没有区别,只是这里的数据是Fragment。

    值得注意的是:设置页面切换时TabLayout样式有两种方式。请注意看代码注释

    第一种主要是使用ViewPager2的registerOnPageChangeCallback方法来控制
    第二种则是通过new TabLayoutMediator来关联TabLayout和ViewPager2进行控制,该方式和ViewPager的setupWithViewPager基本一致,可以算得上是升级到ViewPager2 后的替代方法。

public class LiveFragment extends Fragment {
    private FragmentLiveBinding binding;
    private ArrayList<Fragment> fragmentArrayList;
    private final int LIVE_RECOMMEND = 0;
    private final int LIVE_FOLLOW = 1;

    ......

    @Override
    public void onStart() {
        super.onStart();
        initData();
        initView();
    }

    private void initData(){
        fragmentArrayList = new ArrayList<>();
        fragmentArrayList.add(LIVE_RECOMMEND, new LiveRecommendFragment());
        fragmentArrayList.add(LIVE_FOLLOW, new LiveFollowFragment());
    }
	
	// 以下是第一种方式
    private void initView(){
        LiveViewPagerAdapter liveViewPagerAdapter = new LiveViewPagerAdapter(this);
        liveViewPagerAdapter.setFragmentList(fragmentArrayList);
        binding.vpLiveContainer.setAdapter(liveViewPagerAdapter);
        binding.vpLiveContainer.setCurrentItem(lastPage, false);
    }
    
	private void initEvent() {
		binding.vpLiveContainer.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                if (position == LIVE_FOLLOW) {
                    binding.tvLiveFollow.setTextColor(mContext.getColor(R.color.white));
                    binding.tvLiveRecommend.setTextColor(mContext.getColor(R.color.defaultTextColor));
                } else {
                    binding.tvLiveFollow.setTextColor(mContext.getColor(R.color.defaultTextColor));
                    binding.tvLiveRecommend.setTextColor(mContext.getColor(R.color.white));
                }
                lastPage = position;
            }
        });
	}

	// 这里是第二种方式
	private void initView() {
        GroupTypeViewPagerAdapter groupTypeAdapter = new GroupTypeViewPagerAdapter(this);
        groupTypeAdapter.setFragments(fragments);
        groupListBinding.vpGroupPage.setAdapter(groupTypeAdapter);
        new TabLayoutMediator(groupListBinding.tabLayoutGroup, groupListBinding.vpGroupPage, (tab, position) -> {
            // 可以根据positions设置Tab样式
            if (position == 0) {
                tab.setText(R.string.homeGroupMine);
            } else if (position == 1) {
                tab.setText(R.string.homeGroupInvited);
            }
        }).attach();
    }

}

这样关于ViewPager2的使用就OK了。两者都清楚了,下面说明以下两者区别

ViewPager和ViewPager2的区别

  1. 在布局方面:

    ViewPager允许有子View

    而ViewPager2不允许有子View存在

  2. 在继承方面:

    ViewPager的Adapter继承FragmentStatePagerAdapter

    而ViewPager2的Adapter继承FragmentStateAdapter

  3. 在设置Fragment方面:

    ViewPager可以直接分别设置FragmentList和FragmentTitleList

    而ViewPager2则是只能设置FragmentList(也可能是我没发现,如果有类似FragmentStatePagerAdapter和getPageTitle()方法的烦请告知,谢谢)

  4. 在关联及监听方面:

    ViewPager只需要简单的设置Adapter或者通过TabLayout的setupWithViewPager(ViewPager)方法进行关联。

    而ViewPager2则是需要new TabLayoutMediator()方法或者通过ViewPager2的监听回调registerOnPageChangeCallback()来实现

本篇关于ViewPager和ViewPager2的Blog到此结束,如果有错误,请斧正。

本文地址:https://blog.csdn.net/A_Intelligence/article/details/110873092