ViewPager2中addOnPageChangeListener报错的替代方案
ViewPager2迁移页面监听及TabLayout联动修复方案
问题根因
ViewPager2 对API做了不兼容旧版的重构,不存在旧版ViewPager的addOnPageChangeListener方法,页面切换监听相关的API替换规则如下:
- 注册监听的方法从
addOnPageChangeListener改为registerOnPageChangeCallback - 回调基类从
ViewPager.OnPageChangeListener改为ViewPager2.OnPageChangeCallback
你代码里注释的写法方向正确但语法有误,OnPageChangeCallback没有带外部监听器参数的构造方法,直接传入适配好的TabLayout联动监听实例即可。
最小修改方案
- 删除原有报错的
viewPager.addOnPageChangeListener(...)调用 - 调用
registerOnPageChangeCallback方法,传入TabLayout.TabLayoutOnPageChangeListener实例,实现ViewPager滑动时自动同步TabLayout选中状态 - 原有Tab选中后切换ViewPager页面的逻辑可直接保留,无需修改
修正后可直接运行的代码
package com.example.viewpager; import androidx.appcompat.app.AppCompatActivity; import android.net.Uri; import android.os.Bundle; import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.tabs.TabLayout; public class MainActivity extends AppCompatActivity implements Tab1.OnFragmentInteractionListener, Tab2.OnFragmentInteractionListener, Tab3.OnFragmentInteractionListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TabLayout tabLayout = findViewById(R.id.tabLayout); tabLayout.addTab(tabLayout.newTab().setText("Tab 1")); tabLayout.addTab(tabLayout.newTab().setText("Tab 2")); tabLayout.addTab(tabLayout.newTab().setText("Tab 3")); tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); final ViewPager2 viewPager = findViewById(R.id.pager); final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), getLifecycle()); viewPager.setAdapter(adapter); // 替换原有报错的addOnPageChangeListener调用,注册ViewPager2页面回调实现Tab状态同步 viewPager.registerOnPageChangeCallback(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){ @Override public void onTabSelected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } }); } @Override public void onFragmentInteraction(Uri uri){ } }
补充优化:如果使用1.2.0及以上版本的Material组件库,可以直接用官方提供的
TabLayoutMediator类自动完成双向绑定,不需要手动添加Tab、手写两边的监听逻辑,代码会更简洁,官方也推荐这种写法。
内容的提问来源于stack exchange,提问作者Dua
相关产品推荐
相关产品推荐

