TabLayout+ViewPager实现切换卡布局

前言:TabLayout是sdk 22之后的新特性,TabLayout+ViewPager实现切换卡布局在很多应用上是比较广泛的,同时实现起来也比较简单,交互效果也很不错,今天和大家一起分享其基本用法,在开始使用的时候,可能会遇到不少的坑(反正我是踩到坑了。。。。。。)。
一 引入依赖库:在项目的build.gradle文件下添加库依赖
在这里插入图片描述

  implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'

在这里需要注意的是,依赖库的版本需要与build文件中规定的一致(及与compileSdkVersion,targetSdkVersion保持一致,这里我使用的是compileSdkVersion 28,targetSdkVersion 28,所以版本号为28),否则会报错。

二 xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    tools:context=".TabActivity">
<!--分别设置顶部导航栏的属性-->
    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        app:tabIndicatorHeight="2dp"
        app:tabIndicatorFullWidth="false"
        app:tabMode="scrollable"
        app:tabMinWidth="60dp"
        app:tabPaddingStart="5dp"
        app:tabPaddingEnd="5dp"
        app:tabTextAppearance="@style/TabLayoutTextStyle"
        />

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:layout_weight="1"
        android:background="#ffffff" />

</LinearLayout>

在布局中可以分别设置tabLayout的属性:
app:tabIndicatorHeight 设置导航item底部导航条

app:tabIndicatorFullWidth false 设置item底部导航条不填满item宽度,而是与item的文字等宽, true 表示占满整个item,分别类似于wrap_content match_parent

app:tabMode=“scrollable” 表示当导航栏的数量一次显示不全时,可支持滑动(今日头条顶部导航条是比较典型的例子)

app:tabTextAppearance="@style/TabLayoutTextStyle"用于设置item字体的大小。tabLayout中只能通过这样的方式设置字体的尺寸,具体方法为:

1)在style.xml文件中设置style:

    <style name="TabLayoutTextStyle">
        <item name="android:textSize">@dimen/tab_layout_text_size</item>
    </style>

2)dimen.xml文件中设置字体的尺寸:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="tab_layout_text_size">16dp</dimen>
</resources>

3)最后,在布局中通过app:tabTextAppearance属性引用style文件即可

关于tabLayou的其他属性,大家在使用的时候可以对应的设置即可。

三 Activity中使用:

public class TabActivity extends AppCompatActivity {
    private List<String> mTitleList;
    //这里在使用的时候,如果在导包的过程中与widget包下的TabLayout冲突时,可以直接声明包的全名(我遇到了这个问题,导包的时候总是提示我导入widget下的包,无论各种clean build还是解决不了问题,最后索性直接声明包的全名)
    private android.support.design.widget.TabLayout mTabLayout;
    private ViewPager mViewPager;
    private TabAdapter mTabAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tab);
        initialize();
    }
    private void initialize() {
        mTabLayout = findViewById(R.id.tab_layout);
        mViewPager = findViewById(R.id.view_pager);
        mTitleList = new ArrayList<>();
        //设置导航的内容
        mTitleList.add("推荐");
        mTitleList.add("关注");
        mTitleList.add("小视屏");
        mTitleList.add("视屏");
        mTitleList.add("热点");
        mTitleList.add("北京");
        mTitleList.add("娱乐");
        mTitleList.add("NBA");
        mTitleList.add("其他");
        mTabAdapter = new TabAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mTabAdapter);
        mTabAdapter.setList(mTitleList);
        mTabLayout.setupWithViewPager(mViewPager);

    }
}

这里有一个需要注意的问题就是导包,不要和widget包下TabLayout混淆。实在不行,直接声明全名。

四 FragmentPagerAdapter
由于这里使用的布局是viewPager+fragment的切换布局,因此使用的适配器为FragmentPagerAdapter:

public class TabAdapter extends FragmentPagerAdapter {
    private List<String> mTitleList;
    public TabAdapter(FragmentManager fm) {
        super(fm);
        this.mTitleList = new ArrayList<>();
    }
    public void setList(List<String> datas) {
        this.mTitleList.clear();
        this.mTitleList.addAll(datas);
        notifyDataSetChanged();
    }
    @Override
    public Fragment getItem(int i) {
        ContentFragment fragment = new ContentFragment();
        //通过这样的方式,向对应的fragmen中传递参数,在fragmeng同样通过Bundle接收参数,以区别不同的fragmeng加载不同的数据或者实现不同的逻辑
        Bundle bundle = new Bundle();
        bundle.putString("name", mTitleList.get(i));
        fragment.setArguments(bundle);
        return fragment;
    }
    @Override
    public int getCount() {
        return mTitleList.size();
    }
    @Override
    public CharSequence getPageTitle(int position) {
        String plateName = mTitleList.get(position);
        if (plateName == null) {
            plateName = "";
        } else if (plateName.length() > 15) {
            plateName = plateName.substring(0, 15) + "...";
        }
        return plateName;
    }
}

五 ContentFragment:
1.每一个itemTab对应的fragmeng内容

public class ContentFragment extends Fragment {
    private String mTitle;
    private View mRootView;
    private TextView mTextView;
    public ContentFragment() {
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在这里通过Bundle接收参数
        Bundle bundle = getArguments();
        mTitle = bundle.getString("name");
        if (mTitle == null) {
            mTitle = "参数非法";
        }
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mRootView = inflater.inflate(R.layout.fragment_content, container, false);
        initView(mRootView);
        return mRootView;
    }

    private void initView(View rootView) {
        mTextView = rootView.findViewById(R.id.tv);
        mTextView.setText(mTitle);
    }
}

2.fragment的xml布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ContentFragment">
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"/>

</RelativeLayout>

至此,已完成了TabLayout作为顶部导航,viewPager+Fragmeng进行切换的基本布局。

六 效果图
在这里插入图片描述
在这里插入图片描述
六 总结
1.TabLayout是sdk 22之后的新特性,因此必须要在sdk 22以后才能使用;

2.在导包的时候,若与widget包下的TabLayout冲突时,可直接导入完整包名;

3.在添加依赖库的时候,需要保持与compileSdkVersion,targetSdkVersion版本一致;

4.tabItem字体的设置只能通过tabTextAppearance属性引用Style形式;

5.TabLayout与ViewPager通过 mTabLayout.setupWithViewPager(mViewPager)方法进行关联,也是TabLayout与ViewPager联系起来的核心方法。

由于本人水平有限,以上若存在问题,欢迎指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要禁用TabLayout与ViewPager的左右滑动切换功能,您可以自定义一个ViewPager的子类,并重写它的 `onInterceptTouchEvent` 方法。 首先,创建一个名为 `NonSwipeableViewPager` 的类,并继承自 ViewPager: ```java import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.viewpager.widget.ViewPager; public class NonSwipeableViewPager extends ViewPager { public NonSwipeableViewPager(@NonNull Context context) { super(context); } public NonSwipeableViewPager(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // 返回false,禁止ViewPager的左右滑动切换 return false; } @Override public boolean onTouchEvent(MotionEvent ev) { // 返回false,禁止ViewPager的左右滑动切换 return false; } } ``` 接下来,在您的布局文件中使用 `NonSwipeableViewPager` 替代原来的 ViewPager: ```xml <com.example.NonSwipeableViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 最后,通过以下方式将 TabLayout 与 NonSwipeableViewPager 绑定: ```java TabLayout tabLayout = findViewById(R.id.tabLayout); NonSwipeableViewPager viewPager = findViewById(R.id.viewPager); // 设置ViewPager的适配器 viewPager.setAdapter(adapter); // 将TabLayout与ViewPager关联起来 tabLayout.setupWithViewPager(viewPager); ``` 这样就可以禁用TabLayout与ViewPager的左右滑动切换功能了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易小四

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值