Android中TabLayout+ViewPager禁止滑动,但可点击Tab

本文介绍了如何在Android开发中自定义两种ViewPager子类(NoScrollViewPager和BanViewPager),以实现点击TabLayout时禁止 ViewPager 的滑动手势,仅通过TabLayout控制页面切换。同时提及可能遇到的左右移动bug及其解决方案。

参考网址:https://www.cnblogs.com/zhujiabin/p/7471665.html

1.点击TabLayout去除ViewPager的滑动效果

public class NoScrollViewPager extends ViewPager {
    private boolean noScroll = false;

    public NoScrollViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoScrollViewPager(Context context) {
        super(context);
    }

    public void setNoScroll(boolean noScroll) {
        this.noScroll = noScroll;
    }

    @Override
    public void scrollTo(int x, int y) {
        super.scrollTo(x, y);
    }

    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        if (noScroll)
            return false;
        else
            return super.onTouchEvent(arg0);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        if (noScroll)
            return false;
        else
            return super.onInterceptTouchEvent(arg0);
    }

    @Override
    public void setCurrentItem(int item, boolean smoothScroll) {
        super.setCurrentItem(item, smoothScroll);
    }

    @Override

    public void setCurrentItem(int item) {

        super.setCurrentItem(item, false);//表示切换的时候,不需要切换时间。

    }

}

2.去除ViewPager的滑动效果,只可以通过点击TabLayout进行切换

public class BanViewPager extends ViewPager {

    private boolean isCanScroll = true;
    public BanViewPager(Context context) {
        super(context);
    }
    public BanViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setNoScroll(boolean noScroll) {
        this.isCanScroll = noScroll;
    }

    @Override
    public void scrollTo(int x, int y) {
        super.scrollTo(x, y);
    }

    @Override
    public boolean onTouchEvent(MotionEvent arg0) {

        if (isCanScroll) {
            return false;
        } else {
            return super.onTouchEvent(arg0);

        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        if (isCanScroll) {
            return false;
        } else {
            return super.onInterceptTouchEvent(arg0);

        }

    }

}

注意:若使用此自定义ViewPager还会出现的左右移动bug,可在布局中添加

android:isScrollContainer="true"
<think>我们被要求提供使用TabLayoutViewPager实现顶部导航栏的教程。根据引用的内容,我们可以总结出以下步骤: 1. 在布局XML文件中添TabLayoutViewPager。 2. 创建Fragment(每个标签页的内容)。 3. 创建FragmentPagerAdapter(或FragmentStatePagerAdapter)的子类,用于管理Fragment页面标题。 4. 在Activity(或Fragment)中绑定TabLayoutViewPagerAdapter。 注意:引用[3]提到在Fragment中实现的注意事项,但本例我们以Activity为例。 具体步骤: **步骤1:添依赖** 首先,确保在build.gradle文件中添了Material Components库(包含TabLayoutViewPagerViewPager2是更新的版本,但引用中使用了ViewPager,我们这里按ViewPager2来讲解,因为它是推荐使用的)。 ```groovy dependencies { implementation 'com.google.android.material:material:1.5.0' // 请使用最新版本 implementation "androidx.viewpager2:viewpager2:1.0.0" // 使用ViewPager2 } ``` **步骤2:布局文件中添TabLayoutViewPager** 在activity_main.xml(或你的布局文件)中: ```xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> ``` **步骤3:创建Fragment** 创建两个Fragment(根据你的需要可以多个),例如Fragment1Fragment2。 Fragment1.java: ```java public class Fragment1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment1, container, false); } } ``` 同样创建Fragment2。 **步骤4:创建FragmentStateAdapter** 注意:ViewPager2使用FragmentStateAdapter,而不是以前的FragmentPagerAdapter。 创建一个适配器类,例如ViewPagerAdapter.java: ```java import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.viewpager2.adapter.FragmentStateAdapter; public class ViewPagerAdapter extends FragmentStateAdapter { private static final int TAB_COUNT = 2; // 标签页数量 public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) { super(fragmentActivity); } @NonNull @Override public Fragment createFragment(int position) { // 根据位置返回对应的Fragment switch (position) { case 0: return new Fragment1(); case 1: return new Fragment2(); default: return null; } } @Override public int getItemCount() { return TAB_COUNT; } } ``` **步骤5:在Activity中绑定** 在MainActivity.java中: ```java import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; public class MainActivity extends AppCompatActivity { private TabLayout tabLayout; private ViewPager2 viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tabLayout = findViewById(R.id.tab_layout); viewPager = findViewById(R.id.view_pager); // 设置适配器 ViewPagerAdapter adapter = new ViewPagerAdapter(this); viewPager.setAdapter(adapter); // 将TabLayoutViewPager2关联,并设置标签标题 new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { // 设置每个标签的标题 tab.setText("Tab " + (position + 1)); } ).attach(); } } ``` **注意事项:** - 如果你想要自定义标签视图,可以在`TabLayoutMediator`的lambda表达式中设置,例如设置图标或自定义布局。 - 在Fragment中使用时,注意在Fragment中获取父Activity来初始化适配器(使用getActivity()),但要注意可能为空的情况。 以上是使用TabLayoutViewPager2(ViewPager的升级版)实现顶部导航栏的完整步骤。ViewPager2内部已经使用FragmentStateAdapter,并且与TabLayout的联动通过TabLayoutMediator来实现。 §§相关问题§§ 1. 如何在TabLayout中设置自定义标签视图? 2. ViewPagerViewPager2有什么区别? 3. 如何实现TabLayout滑动效果动画? </think>### 使用 TabLayout ViewPager 实现顶部导航栏的完整教程 #### 实现步骤 1. **添依赖** 在 `build.gradle` 中添 Material Design ViewPager2 依赖: ```gradle dependencies { implementation 'com.google.android.material:material:1.6.0' // TabLayout implementation 'androidx.viewpager2:viewpager2:1.0.0' // ViewPager2 } ``` 2. **布局文件配置** ```xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.google.android.material.tabs.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> ``` 3. **创建 Fragment** 每个导航标签对应一个 Fragment: ```java public class Tab1Fragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_tab1, container, false); } } ``` 4. **适配器实现** 继承 `FragmentStateAdapter`: ```java public class TabAdapter extends FragmentStateAdapter { private final Fragment[] fragments = { new Tab1Fragment(), new Tab2Fragment(), new Tab3Fragment() }; public TabAdapter(FragmentActivity fa) { super(fa); } @NonNull @Override public Fragment createFragment(int position) { return fragments[position]; } @Override public int getItemCount() { return fragments.length; } } ``` 5. **Activity 绑定逻辑** ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TabLayout tabLayout = findViewById(R.id.tabLayout); ViewPager2 viewPager = findViewById(R.id.viewPager); // 设置适配器 viewPager.setAdapter(new TabAdapter(this)); // 绑定TabLayoutViewPager new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { tab.setText("标签 " + (position + 1)); // 设置标签标题 }).attach(); } } ``` #### 关键特性说明 1. **滑动特效** TabLayout 默认支持滑动过渡动画,可通过 `app:tabIndicatorAnimationMode="elastic"` 启用弹性动画[^1]。 2. **标签模式** - `app:tabMode="fixed"`:平均分布标签(适合少量标签) - `app:tabMode="scrollable"`:可横向滚动(适合多标签) 3. **注意事项** - 在 Fragment 中使用时需用 `getActivity()` 初始化适配器[^3] - 使用 `FragmentStateAdapter` 替代已废弃的 `FragmentPagerAdapter` - ViewPager2 默认支持垂直方向滑动(通过 `android:orientation="vertical"`) #### 优化建议 1. **自定义标签视图**: ```java TabLayout.Tab tab = tabLayout.getTabAt(0); if (tab != null) { tab.setCustomView(R.layout.custom_tab); // 自定义布局 } ``` 2. **添图标**: ```java tab.setIcon(R.drawable.ic_home); // 设置图标 tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { // 选中时切换图标 tab.setIcon(R.drawable.ic_home_filled); } }); ``` --- ### 常见问题解答 **Q1: 如何在 Fragment 中使用此方案?** ```java // 在 Fragment 中初始化 ViewPager2 viewPager = getView().findViewById(R.id.viewPager); viewPager.setAdapter(new TabAdapter(requireActivity())); // 使用 requireActivity() ``` **Q2: 如何禁用 ViewPager 滑动?** ```java viewPager.setUserInputEnabled(false); // 禁止手动滑动 ``` **Q3: 如何监听标签切换事件?** ```java tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { // 标签选中时触发 } }); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值