abLayout+ViewPager2+Fragment 四个页面以上:当从第一页切换到第四页、会依次从二、三滚动到第四页。页面跨越越多个效果越明显,体验很不好,怎么关闭平滑滚动动画,而是点击tab后直接跳转到相应的页面呢?
ViewPager的setCurrentItem(int item, boolean smoothScroll)方法smoothScroll=false可以直接跳转,我们可以自定义一个ViewPager重写改方法实现。
但是ViewPager2是final类,只能另辟蹊径: 我想控制点击TabLayout 使ViewPager2滚动核心是通过TabLayoutMediator进行绑定,先看源码看有三个构造函数:
public TabLayoutMediator(
@NonNull TabLayout tabLayout,
@NonNull ViewPager2 viewPager,
@NonNull TabConfigurationStrategy tabConfigurationStrategy) {
this(tabLayout, viewPager, /* autoRefresh= */ true, tabConfigurationStrategy);
}
public TabLayoutMediator(
@NonNull TabLayout tabLayout,
@NonNull ViewPager2 viewPager,
boolean autoRefresh,
@NonNull TabConfigurationStrategy tabConfigurationStrategy) {
this(tabLayout, viewPager, autoRefresh, /* smoothScroll= */ true, tabConfigurationStrategy);
}
public TabLayoutMediator(
@NonNull TabLayout tabLayout,
@NonNull ViewPager2 viewPager,
boolean autoRefresh,
boolean smoothScroll,
@NonNull TabConfigurationStrategy tabConfigurationStrategy) {
this.tabLayout = tabLayout;
this.viewPager = viewPager;
this.autoRefresh = autoRefresh;
this.smoothScroll = smoothScroll;
this.tabConfigurationStrategy = tabConfigurationStrategy;
}
可以看出第三个构造函数有smoothScroll入参,TabLayoutMediator类继续往下看这个参数是用来做什么的?
public void attach() {
if (attached) {
throw new IllegalStateException("TabLayoutMediator is already attached");
}
……
// Now we'll add a tab selected listener to set ViewPager's current item
onTabSelectedListener = new ViewPagerOnTabSelectedListener(viewPager, smoothScroll); // 在被这里传入监听器
……
}
// 再看看监听器里面的做了什么?
@Override
public void onTabSelected(@NonNull TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition(), smoothScroll);
}
/**
*设置当前选定的页面。如果{@code smoothScroll=true},将执行平滑
*从当前项目到新项目的动画。如果未设置适配器,则静默忽略
*或者是空的。将项夹到适配器的边界。
*
*@param item要选择的项目索引
*@param smoothScroll True可平滑滚动到新项目,false可立即转换
*/
public void setCurrentItem(int item, boolean smoothScroll) {
if (isFakeDragging()) {
throw new IllegalStateException("Cannot change current item when ViewPager2 is fake "
+ "dragging");
}
setCurrentItemInternal(item, smoothScroll);
}
所以我们可以使用第三个构造函数来关闭平滑滚动效果:
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(binding.tablayout, binding.viewPager2, true, false, (tab, position) -> {
// 这里初始化Tab自定义
tab.setCustomView(R.layout.custom_tab_view);
});
tabLayoutMediator.attach();