Android:仅满足if条件时才允许滑动切换至下一个Tab
当然可行!这种场景在表单类的滑动页面里太常见了,咱们可以通过拦截滑动事件或者利用ViewPager的相关回调来实现。核心是在用户尝试切换页面时先校验条件,只有满足要求才允许切换。下面分两种主流的ViewPager版本来一步步讲解:
针对ViewPager(旧版)的实现
我们可以自定义一个ViewPager子类,重写触摸事件拦截方法,在里面加入条件判断:
1. 自定义可拦截滑动的ViewPager
public class LockableViewPager extends ViewPager { private OnSwipePermissionListener permissionListener; public LockableViewPager(Context context) { super(context); } public LockableViewPager(Context context, AttributeSet attrs) { super(context, attrs); } public void setOnSwipePermissionListener(OnSwipePermissionListener listener) { this.permissionListener = listener; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // 检查是否允许当前页面的滑动操作 if (permissionListener != null && !permissionListener.isSwipeAllowed(getCurrentItem())) { // 条件不满足时拦截滑动事件 return false; } return super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { if (permissionListener != null && !permissionListener.isSwipeAllowed(getCurrentItem())) { return false; } return super.onTouchEvent(ev); } // 定义回调接口,让外部提供校验逻辑 public interface OnSwipePermissionListener { boolean isSwipeAllowed(int currentPage); } }
2. 在Activity中配置并添加校验逻辑
LockableViewPager viewPager = findViewById(R.id.view_pager); // 设置适配器(你的原有适配器代码不变) viewPager.setAdapter(yourPagerAdapter); // 绑定TabLayout(原有绑定逻辑不变) TabLayout tabLayout = findViewById(R.id.tab_layout); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { tab.setText("页面" + (position + 1)); }).attach(); // 添加滑动权限校验 viewPager.setOnSwipePermissionListener(currentPage -> { // 仅对第一个页面(索引0)做校验 if (currentPage == 0) { // 获取第一个Fragment实例 FirstFragment firstFragment = (FirstFragment) getSupportFragmentManager() .findFragmentByTag("android:switcher:" + R.id.view_pager + ":0"); if (firstFragment != null) { // 获取EditText内容并判断是否为空 String inputContent = firstFragment.getEditTextContent(); boolean isAllowed = !TextUtils.isEmpty(inputContent.trim()); // 如果不允许,给用户提示 if (!isAllowed) { Toast.makeText(this, "请先填写内容再切换页面", Toast.LENGTH_SHORT).show(); } return isAllowed; } } // 其他页面默认允许滑动 return true; });
3. 在第一个Fragment中提供获取EditText内容的方法
public class FirstFragment extends Fragment { private EditText inputEt; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_first, container, false); inputEt = view.findViewById(R.id.et_input); return view; } // 暴露方法给Activity获取输入内容 public String getEditTextContent() { return inputEt.getText().toString(); } }
针对ViewPager2(新版)的实现
ViewPager2基于RecyclerView实现,我们可以通过拦截触摸事件来实现同样的效果:
1. 自定义触摸拦截器
public class ViewPager2SwipeInterceptor implements View.OnTouchListener { private final ViewPager2 viewPager2; private final OnSwipePermissionListener permissionListener; private float startTouchX; public ViewPager2SwipeInterceptor(ViewPager2 viewPager2, OnSwipePermissionListener permissionListener) { this.viewPager2 = viewPager2; this.permissionListener = permissionListener; } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startTouchX = event.getX(); break; case MotionEvent.ACTION_MOVE: float endTouchX = event.getX(); int currentPage = viewPager2.getCurrentItem(); // 判断是否是从第一个页面向左滑(尝试切换到第二个页面) if (endTouchX < startTouchX && currentPage == 0) { if (!permissionListener.isSwipeAllowed(currentPage)) { Toast.makeText(v.getContext(), "请先填写内容再切换页面", Toast.LENGTH_SHORT).show(); return true; // 拦截滑动事件 } } break; } return false; // 其他情况不拦截 } public interface OnSwipePermissionListener { boolean isSwipeAllowed(int currentPage); } }
2. 在Activity中配置拦截器
ViewPager2 viewPager2 = findViewById(R.id.view_pager2); viewPager2.setAdapter(yourFragmentStateAdapter); // 绑定TabLayout TabLayout tabLayout = findViewById(R.id.tab_layout); new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { tab.setText("页面" + (position + 1)); }).attach(); // 设置触摸拦截器 viewPager2.setOnTouchListener(new ViewPager2SwipeInterceptor(viewPager2, currentPage -> { if (currentPage == 0) { // 获取第一个Fragment实例(ViewPager2的Fragment获取方式略有不同,也可以用ViewModel共享数据) FirstFragment firstFragment = (FirstFragment) getSupportFragmentManager() .findFragmentById(R.id.view_pager2); if (firstFragment != null) { return !TextUtils.isEmpty(firstFragment.getEditTextContent().trim()); } } return true; }));
额外注意:拦截TabLayout的点击切换
除了滑动,用户可能直接点击TabLayout的标签切换页面,所以我们也要拦截这种操作:
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { int currentPage = viewPager2.getCurrentItem(); int targetPage = tab.getPosition(); // 仅拦截从第一个页面到第二个页面的点击 if (currentPage == 0 && targetPage == 1) { FirstFragment firstFragment = (FirstFragment) getSupportFragmentManager() .findFragmentById(R.id.view_pager2); if (firstFragment != null && TextUtils.isEmpty(firstFragment.getEditTextContent().trim())) { // 取消选中目标Tab,保持当前页面 tabLayout.getTabAt(currentPage).select(); Toast.makeText(MainActivity.this, "请先填写内容再切换页面", Toast.LENGTH_SHORT).show(); return; } } viewPager2.setCurrentItem(targetPage); } @Override public void onTabUnselected(TabLayout.Tab tab) {} @Override public void onTabReselected(TabLayout.Tab tab) {} });
内容的提问来源于stack exchange,提问作者Konstantinos Evangelidis
相关产品推荐
相关产品推荐

