ViewPager2 使用

编程入门 行业动态 更新时间:2024-10-15 20:21:49

ViewPager2 使用

ViewPager2 使用

一、什么是ViewPager?

布局管理器允许左右翻转带数据的页面,你想要显示的视图可以通过实现PagerAdapter来显示。这个类其实是在早期设计和开发的,它的API在后面的更新之中可能会被改变,当它们在新版本之中编译的时候可能还会改变源码。


ViewPager经常用来连接Fragment,它很方便管理每个页面的生命周期,使用ViewPager管理Fragment是标准的适配器实现。最常用的实现一般有FragmentPagerAdapter和FragmentStatePagerAdapter。

ViewPager是android扩展包v4包中的类,这个类可以让我们左右切换当前的view。我们先来聊聊ViewPager的几个相关知识点:

  • 1、ViewPager类直接继承了ViewGroup类,因此它一个容器类,可以添加其他的view类
  • 2、ViewPager类需要一个PagerAdapter适配器类给它提供数据(这点跟ListView一样需要数据适配器Adater)
  • 3、ViewPager经常和Fragment一起使用,并且官方还提供了专门的FragmentPagerAdapterFragmentStatePagerAdapter类供Fragment中的ViewPager使用

二、什么是ViewPager2

原理: viewpager2 内部实现原理是使用recycleview加LinearLayoutManager实现竖直滚动,其实可以理解为对recyclerview的二次封装

private void initialize(Context context, AttributeSet attrs) {mAccessibilityProvider = sFeatureEnhancedA11yEnabled? new PageAwareAccessibilityProvider(): new BasicAccessibilityProvider();// 实例化recycleview对象mRecyclerView = new RecyclerViewImpl(context);mRecyclerView.setId(ViewCompat.generateViewId());mRecyclerView.setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS);// 实例化LinearLayoutManager对象mLayoutManager = new LinearLayoutManagerImpl(context);mRecyclerView.setLayoutManager(mLayoutManager);mRecyclerView.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING);setOrientation(context, attrs);mRecyclerView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));mRecyclerView.addOnChildAttachStateChangeListener(enforceChildFillListener());// Create ScrollEventAdapter before attaching PagerSnapHelper to RecyclerView, because the// attach process calls PagerSnapHelperImpl.findSnapView, which uses the mScrollEventAdaptermScrollEventAdapter = new ScrollEventAdapter(this);// Create FakeDrag before attaching PagerSnapHelper, same reason as abovemFakeDragger = new FakeDrag(this, mScrollEventAdapter, mRecyclerView);mPagerSnapHelper = new PagerSnapHelperImpl();mPagerSnapHelper.attachToRecyclerView(mRecyclerView);// Add mScrollEventAdapter after attaching mPagerSnapHelper to mRecyclerView, because we// don't want to respond on the events sent out during the attach processmRecyclerView.addOnScrollListener(mScrollEventAdapter);mPageChangeEventDispatcher = new CompositeOnPageChangeCallback(3);mScrollEventAdapter.setOnPageChangeCallback(mPageChangeEventDispatcher);// Callback that updates mCurrentItem after swipes. Also triggered in other cases, but in// all those cases mCurrentItem will only be overwritten with the same value.final OnPageChangeCallback currentItemUpdater = new OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {if (mCurrentItem != position) {mCurrentItem = position;mAccessibilityProvider.onSetNewCurrentItem();}}@Overridepublic void onPageScrollStateChanged(int newState) {if (newState == SCROLL_STATE_IDLE) {updateCurrentItem();}}};// Prevents focus from remaining on a no-longer visible pagefinal OnPageChangeCallback focusClearer = new OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {clearFocus();if (hasFocus()) { // if clear focus did not succeedmRecyclerView.requestFocus(View.FOCUS_FORWARD);}}};// Add currentItemUpdater before mExternalPageChangeCallbacks, because we need to update// internal state firstmPageChangeEventDispatcher.addOnPageChangeCallback(currentItemUpdater);mPageChangeEventDispatcher.addOnPageChangeCallback(focusClearer);// Allow a11y to register its listeners after currentItemUpdater (so it has the// right data). TODO: replace ordering comments with a test.mAccessibilityProvider.onInitialize(mPageChangeEventDispatcher, mRecyclerView);mPageChangeEventDispatcher.addOnPageChangeCallback(mExternalPageChangeCallbacks);// Add mPageTransformerAdapter after mExternalPageChangeCallbacks, because page transform// events must be fired after scroll eventsmPageTransformerAdapter = new PageTransformerAdapter(mLayoutManager);mPageChangeEventDispatcher.addOnPageChangeCallback(mPageTransformerAdapter);attachViewToParent(mRecyclerView, 0, mRecyclerView.getLayoutParams());
}

ViewPager2的出现是为了替代ViewPager,它有以下几个优势:

  • 支持RTL布局,
  • 支持竖向滚动
  • 支持notifyDataSetChanged

RTL布局是Right To Left布局也就是从右往左的布局,大家知道我们平常写的布局都是从左往右,但是如果你适配阿拉伯语等环境的UI布局,他们的写法是从右往左的,具体这里不做研究。

API的变动:

FragmentStateAdapter替换了原来的 FragmentStatePagerAdapter

RecyclerView.Adapter替换了原来的 PagerAdapter

registerOnPageChangeCallback替换了原来的 addPageChangeListener

FragmentStateAdapter和FragmentStatePagerAdapter作用相同, 可以用viewpager来管理fragment, 区别在于viewpager2的FragmentStateAdapter与recycleview的生命周期绑定

另外viewpager2的Adapter是继承自recyclerview的adapter, 支持除了notifyDataSetChanged()以外的notifyItemChanged(int position)等方式, 使用上更加的便捷

三、ViewPager2 结合 Fragment实际demo

在app模块的build.gradle里要加上这两个依赖

implementation "androidx.viewpager2:viewpager2:1.1.0-beta02"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

myfragment.xml

一个显示在屏幕正中央的文字mode1

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent"android:background="#FF9800"android:orientation="vertical"android:gravity="center"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="mode1"android:textSize="30sp"/>
</LinearLayout>

myfragment2.xml

一个显示在屏幕正中央的文字mode2

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent"android:background="#FF0000"android:orientation="vertical"android:gravity="center"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="mode2"android:textSize="30sp"/>
</LinearLayout>

activity_main.xml

一个TabLayout和一个ViewPager2组件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""xmlns:app=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><com.google.android.material.tabs.TabLayoutandroid:id="@+id/my_tab"android:layout_width="match_parent"android:layout_height="60dp"/><androidx.viewpager2.widget.ViewPager2android:id="@+id/my_pager2"android:layout_width="match_parent"android:layout_height="match_parent"/>
</LinearLayout>

MyAdapter.java

重写MyAdapter、createFragment、getItemCount三个方法

package com.example.viewpager2;import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.lifecycle.Lifecycle;
import java.util.List;public class MyAdapter extends FragmentStateAdapter {List<Fragment> fragments;public MyAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, List<Fragment> fragments) {super(fragmentManager, lifecycle);this.fragments = fragments;}@NonNull@Overridepublic Fragment createFragment(int position) {return fragments.get(position);}@Overridepublic int getItemCount() {return fragments.size();}
}

MyFragment.java

实现第一个fragment页面

package com.example.viewpager2;import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;public class MyFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.myfragment, null);}
}

MySecondFragment.java

实现第二个fragment页面

package com.example.viewpager2;import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;public class MySecondFragment extends Fragment {@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.myfragment2, null);}}

MainActivity.java

进来的activity

package com.example.viewpager2;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;import android.os.Bundle;import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private TabLayout myTab;private ViewPager2 myPager2;List<String> titles=new ArrayList<>();List<Fragment> fragments=new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myTab = findViewById(R.id.my_tab);myPager2 = findViewById(R.id.my_pager2);//添加标题titles.add("1");titles.add("2");//添加Fragment进去fragments.add(new MyFragment());fragments.add(new MySecondFragment());//实例化适配器MyAdapter myAdapter=new MyAdapter(getSupportFragmentManager(),getLifecycle(),fragments);//设置适配器myPager2.setAdapter(myAdapter);//TabLayout和Viewpager2进行关联new TabLayoutMediator(myTab, myPager2, new TabLayoutMediator.TabConfigurationStrategy() {public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {tab.setText(titles.get(position));}}).attach();}
}

ViewPager + Fragment 实现tab页切换不同页面内容的效果

参考:【精选】Android:ViewPager \ViewPager2 简单介绍 & 使用方法解析_viewpager2与viewpager-CSDN博客

更多推荐

ViewPager2 使用

本文发布于:2023-11-15 18:56:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1604564.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!