花木网站源码,建立网站目录结构的意义,wordpress快速编辑添加多个标签,南宁网站开发公司1.ViewPager的简介和作用 ViewPager是android扩展包v4包中的类#xff0c;这个类可以让用户左右切换当前的view#xff0c;用于允许用户在几个页面#xff08;或称为碎片#xff09;之间左右滑动切换。它通常用于创建像画廊或轮播图那样的用户体验。 ViewPager类直接继承了…1.ViewPager的简介和作用 ViewPager是android扩展包v4包中的类这个类可以让用户左右切换当前的view用于允许用户在几个页面或称为碎片之间左右滑动切换。它通常用于创建像画廊或轮播图那样的用户体验。 ViewPager类直接继承了ViewGroup类所有它是一个容器类可以在其中添加其他的view类。ViewPager类需要一个PagerAdapter适配器类给它提供数据。ViewPager经常和Fragment一起使用并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用。 作用 ViewPager 的主要作用包括 页面滑动允许用户通过水平滑动来切换不同的页面。动画效果提供平滑的页面切换动画增强用户体验。页面预加载可以配置 ViewPager 预加载相邻的页面这样用户在滑动时页面切换更加流畅。页面指示器通常与 TabLayout 或其他指示器组件结合使用显示当前页面的位置和总数。页面适配器通过适配器模式可以灵活地管理页面的内容适配器负责提供页面视图。自定义页面转换开发者可以通过实现 PageTransformer 接口来自定义页面滑动时的动画和转换效果。事件监听提供页面切换的监听器如 OnPageChangeListener以便在页面切换时执行特定的操作。 2.ViewPager的适配器 简介中提到了PagerAdapter和ListView等控件使用一样,需要ViewPager设置PagerAdapter来完成页面和数据的绑定
这个PagerAdapter是一个基类适配器我们经常用它来实现app引导图它的子类有FragmentPagerAdapter和FragmentStatePagerAdapter,这两个子类适配器用于和Fragment一起使用在安卓应用中它们就像listview一样出现的频繁。
适配器ViewPager主要有两种Adapter用于适配填充Fragment。
PagerAdapter 是 Android 中的一个抽象类用于为 ViewPager 提供数据和视图。当你想要在 ViewPager 中展示一系列的页面时你需要创建一个 PagerAdapter 的子类来管理这些页面。
public class MyPagerAdapter extends PagerAdapter {private Context context;private ListFragment fragments;public MyPagerAdapter(Context context, ListFragment fragments) {this.context context;this.fragments fragments;}Overridepublic Object instantiateItem(ViewGroup container, int position) {//必须实现用于实例化Fragment fragment fragments.get(position);FragmentManager fragmentManager ((FragmentActivity) context).getSupportFragmentManager();fragmentManager.beginTransaction().add(container.getId(), fragment, fragment position).commit();return fragment;}Overridepublic void destroyItem(ViewGroup container, int position, Object object) {//必须实现销毁FragmentManager fragmentManager ((FragmentActivity) context).getSupportFragmentManager();fragmentManager.beginTransaction().remove((Fragment) object).commit();}Overridepublic int getCount() {//必须实现return fragments.size();}Overridepublic boolean isViewFromObject(View view, Object object) {//必须实现return view.equals(object);}
}
一个PagerAdapter 需要至少实现这四个方法
这个东西是一个基类我们常用的viewpagerfragment主要使用他的子类FragmentPagerAdapter和FragmentStatePagerAdapter
首先是FragmentPagerAdapter 特点 每个页面一个 FragmentFragmentPagerAdapter 为 ViewPager 的每个页面创建一个 Fragment 实例。内存效率FragmentPagerAdapter 会保留所有页面的 Fragment 对象这意味着用户在页面间切换时页面状态不会丢失但这也可能导致更多的内存使用。易于实现相比于 PagerAdapterFragmentPagerAdapter 提供了更简单的 API 来管理 Fragment。 private static class FragmentAdapter extends FragmentPagerAdapter{private ArrayListFragment fragments;public FragmentAdapter(FragmentManager fm,ArrayListFragment fragments) {super(fm);this.fragments fragments;}Overridepublic Fragment getItem(int position) {return fragments.get(position);}Overridepublic int getCount() {return fragments.size();}}
FragmentStatePagerAdapter: 主要特点 按需加载当用户浏览到某个页面时FragmentStatePagerAdapter 会创建该页面的 Fragment而当用户离开该页面时对应的 Fragment 可能会被销毁以节省内存。状态保存FragmentStatePagerAdapter 会在 Fragment 被销毁前保存其状态以便在用户返回该页面时恢复 Fragment 的状态。适用于大量页面由于它会销毁不在屏幕上的 Fragment因此更适合用于拥有大量页面的 ViewPager。 private static class FragmentStateAdapter extends FragmentStatePagerAdapter{private ArrayListFragment fragments;public FragmentStateAdapter(FragmentManager fm,ArrayListFragment fragments) {super(fm);this.fragments fragments;}Overridepublic Fragment getItem(int position) {return fragments.get(position);}Overridepublic int getCount() {return fragments.size();}}
与 FragmentPagerAdapter 相比FragmentStatePagerAdapter 更适合用于页面数量较多的情况。FragmentPagerAdapter 会保留所有页面的 Fragment 在内存中而 FragmentStatePagerAdapter 则仅在需要时加载 Fragment这样可以减少内存的使用。
在fragment中的区别 ViewPager默认会保留当前页和前后两页的内容即一共三页。首页之前没有了所以只保留当前页和后一页对于不保留的内容FragmentPagerAdapter 只进行到对Fragment的destroyView不会destroy和detach而FragmentStatePagerAdapter会执行destroy和detach当划回去的时候会再次执行attach和create因此FragmentPagerAdapter适用于数量较少的场景用空间换时间FragmentStatePagerAdapter适用于数量较多的场景每次会执行destroy节约内存。 3.viewpager2
首先介绍一下viewpager2 基于 RecyclerViewViewPager2 是建立在 RecyclerView 基础上的因此它继承了 RecyclerView 的所有优点如高效的视图回收机制和灵活的布局管理。灵活的缓存策略ViewPager2 允许开发者通过 offscreenPageLimit 属性来控制预加载的页面数量提供了更灵活的缓存策略。支持垂直和水平滑动ViewPager2 支持垂直滑动这使得它可以在不同的布局方向上使用。适配器使用 RecyclerView.Adapter 或 FragmentStateAdapter 作为其适配器。FragmentStateAdapter 是专为 ViewPager2 设计的用于管理 Fragment 的生命周期。新特性ViewPager2 支持更多的自定义动画和转换效果可以通过 PageTransformer 来实现。更好的性能由于基于 RecyclerViewViewPager2 在性能上通常优于 ViewPager特别是在处理大量数据或复杂布局时。 ViewPager2 的运作机制
ViewPager2 的运作离不开两个关键组件PagerAdapter 和 PageTransformer。PagerAdapter例如 FragmentStatePagerAdapter 或 FragmentPagerAdapter负责管理 Fragment 的集合根据当前位置创建或销毁 Fragment。
PageTransformer 则用于控制页面之间的过渡效果。开发者可以自定义 PageTransformer实现缩放、平移或淡入淡出的效果为用户提供更加流畅、生动的视觉体验。
我们以常用的ViewPager2的多Fragment页面切换为例展示一下使用
1.制作一个fragment的xml文件
?xml version1.0 encodingutf-8?
androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentxmlns:toolshttp://schemas.android.com/toolstools:context.View.myFragmentcom.example.weatherwindknow.View.MyViewandroid:idid/mvandroid:layout_width200dpandroid:layout_height200dpandroid:layout_gravitycenter_horizontalapp:layout_constraintBottom_toBottomOfparentapp:layout_constraintEnd_toEndOfparentapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparent //androidx.constraintlayout.widget.ConstraintLayout
我们在这里绑定了我们的类
在fragment类中
public class myFragment extends Fragment {FragmentMyBinding binding;NullableOverridepublic View onCreateView(NonNull LayoutInflater inflater, Nullable ViewGroup container, Nullable Bundle savedInstanceState) {binding FragmentMyBinding.inflate(inflater,container,false);return binding.getRoot();}Overridepublic void onDestroyView() {super.onDestroyView();binding null;}
}2、制作Adapter
我们可以直接使用上面的示例
这里我们使用FragmentStateAdapter。
public class MyviewPagerAdapter extends FragmentStateAdapter {ListFragment List;public MyviewPagerAdapter(NonNull FragmentActivity fragmentActivity, ListFragment fragmentList) {super(fragmentActivity);this.List fragmentList;}NonNullOverridepublic Fragment createFragment(int position) {return List.get(position);}Overridepublic int getItemCount() {return List ! null ? List.size() : 0;}
} createFragment用于返回指定的frgment界面 getItemCount用于加载容器大小 3.在活动中使用 ListFragment fragmentList new ArrayList();fragmentList.add(new myFragment());fragmentList.add(new myFragment());fragmentList.add(new myFragment());fragmentList.add(new myFragment());fragmentList.add(new myFragment());MyviewPagerAdapter adapter new MyviewPagerAdapter(this,fragmentList);binding.viewPager.setAdapter(adapter);
我们这里可以看出来逻辑首先加载数据再把数据加载进适配器再设置适配器。
4.TabLayout / 指示器CircleIndicator
这两个东西的作用是一个知识器的效果
我们先来介绍指示器CircleIndicator这是一个简单的圆点指示器我们使用时
首先引入库
implementation me.relex:circleindicator:2.1.6
其次将这个加入我们的布局中一般使用是RelativeLayout
RelativeLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentme.relex.circleindicator.CircleIndicator3android:idid/indicatorandroid:layout_widthmatch_parentandroid:layout_height48dpapp:ci_width5dpapp:ci_height5dpapp:ci_margin5dpapp:ci_orientationhorizontalapp:ci_gravitycenter/androidx.viewpager2.widget.ViewPager2android:idid/viewPagerandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationhorizontal/
/RelativeLayout
之后开始使用,依据如下步骤即可使用
ViewPager2 viewpager view.findViewById(R.id.viewpager);
viewpager.setAdapter(mAdapter);CircleIndicator3 indicator view.findViewById(R.id.indicator);
indicator.setViewPager(viewpager);
adapter.registerAdapterDataObserver(indicator.getAdapterDataObserver());
接下来介绍tablayout
首先加入布局中 LinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticalcom.google.android.material.tabs.TabLayoutandroid:idid/tabsandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentapp:tabModefixed /androidx.viewpager2.widget.ViewPager2android:idid/viewPagerandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationhorizontal/ /LinearLayout之后在代码中将两个关联一下即可
// 将 TabLayout 与 ViewPager 关联
tabLayout.setupWithViewPager(viewPager);
自定义标签我们可以自定义标签的文本、图标。
TabLayout tabLayout findViewById(R.id.tabs);// 添加标签
tabLayout.addTab(tabLayout.newTab().setText(标签1));
tabLayout.addTab(tabLayout.newTab().setText(标签2));
tabLayout.addTab(tabLayout.newTab().setText(标签3));// 设置标签的图标
tabLayout.getTabAt(0).setIcon(R.drawable.ic_tab1);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_tab2);
tabLayout.getTabAt(2).setIcon(R.drawable.ic_tab3);
除了代码设置我们还可以静态改变设置两个样式分别代表选中未选中app:tabTextAppearancestyle/TabLayoutTextUnSelected
监听标签的点击事件我们可以为标签设置点击事件监听器。
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {Overridepublic void onTabSelected(TabLayout.Tab tab) {// 当标签被选中时}Overridepublic void onTabUnselected(TabLayout.Tab tab) {// 当标签未被选中时}Overridepublic void onTabReselected(TabLayout.Tab tab) {// 当标签被重新选中时}
});
动态添加和删除标签我们可以在运行时动态地添加和删除标签。
// 添加标签
TabLayout.Tab newTab tabLayout.newTab();
newTab.setText(新标签);
tabLayout.addTab(newTab);// 删除标签
tabLayout.removeTabAt(index);
tablayout监听 binding.tabMode.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {TextView textView new TextView(MainActivity.this);Overridepublic void onTabSelected(TabLayout.Tab tab) {//选中时的变化}public void onTabUnselected(TabLayout.Tab tab) {//未选中的变化}Overridepublic void onTabReselected(TabLayout.Tab tab) {//重复选中的变化当用户再次点击已经选中的Tab时这个方法就会被调用。}});我们可以在 onTabSelected中处理选中的时候情况更改样式等等但是要在 onTabSelected中设置内容并且在 onTabUnSelected中清除掉我们的样式否则会出现叠加爆掉的情况