TabLayout+Fragment+ViewPager的实现——篇一

        利用TabLayout+Fragment+ViewPager实现标题栏和内容的联动效果是一种比较简单的小功能,现在就让我来带大家看一下如何实现以上功能吧!

一.TabLayout+Fragment+ViewPager+FragmentPagerAdapter:

1.Fragment的布局文件:

        这里的布局只是简单地写了一个TextView,如果大家需要实现其它样式的布局,可以自己进行设计编码。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是一个Fragment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

2.Fragment类文件:

package com.example.myapplication.fragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


import androidx.fragment.app.Fragment;

import com.example.myapplication.R;

public class FirstFragment extends Fragment {


    private View mRootView;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mRootView = inflater.inflate(R.layout.fragment_first, container, false);
        return mRootView;
    }
}

3.Activity的布局文件:

        在Activity布局文件中分别引入TabLayout和ViewPager,其中TabLaout需要引入以下TabLayout的依赖包,虽然我发现我本地环境没有添加这个依赖包也是可以的。

 //添加TabLayout依赖包
    implementation 'com.google.android.material:material:1.0.0'

        布局编码如下:        

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="@+id/tab_layout"
        app:layout_constraintTop_toBottomOf="@id/tab_layout" />

</androidx.constraintlayout.widget.ConstraintLayout>

4.Activity的类文件:

        Activity的类文件如下所示,在这里,三个页面的Fragment都使用的用一个类文件和布局文件,具体的开发中需要自己按照需求分别添加不同的Fragmet类文件以及对应的布局文件。这里面使用的适配器是FragmentPagerAdapter,目前这种方法处于不推荐使用的状态。

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.os.Bundle;

import com.example.myapplication.fragment.FirstFragment;
import com.google.android.material.tabs.TabLayout;

import java.util.ArrayList;


public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTabLayout = findViewById(R.id.tab_layout);
        mViewPager = findViewById(R.id.viewpager);
        initData();
    }

    private void initData() {

        //创建数组链表
        ArrayList<Fragment> mFragmentList = new ArrayList<>();
        ArrayList<String> mTitle = new ArrayList<>();

        //向Fragment数组链表中添加Fragment数据
        mFragmentList.add(new FirstFragment());
        mFragmentList.add(new FirstFragment());
        mFragmentList.add(new FirstFragment());

        //向Title数组链表中添加字符串数据
        mTitle.add("标题1");
        mTitle.add("标题2");
        mTitle.add("标题3");

        //初始化适配器
        FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {

            //获取页面的数量
            @Override
            public int getCount() {
                return mFragmentList.size();
            }

            //返回指定页面的Fragment
            @Override
            public Fragment getItem(int position) {
                return mFragmentList.get(position);
            }

            //返回指定页面的标题
            @Override
            public CharSequence getPageTitle(int position) {
                return mTitle.get(position);
            }
        };

        //为ViewPager
        mViewPager.setAdapter(adapter);

        //将ViewPager和TabLayout关联绑定起来
        mTabLayout.setupWithViewPager(mViewPager);
    }


}

二.TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter:

        其它的代码和上面都是一样的,这里面就只贴出不一样的Activity的类文件,其实这里面也是百分之九十五的一样。同样这里面使用的适配器FragmentStatePagerAdapter也处于不推荐使用的状态。

1.Activity的类文件:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.os.Bundle;

import com.example.myapplication.fragment.FirstFragment;
import com.google.android.material.tabs.TabLayout;

import java.util.ArrayList;


public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTabLayout = findViewById(R.id.tab_layout);
        mViewPager = findViewById(R.id.viewpager);
        initData();
    }

    private void initData() {

        //创建数组链表
        ArrayList<Fragment> mFragmentList = new ArrayList<>();
        ArrayList<String> mTitle = new ArrayList<>();

        //向Fragment数组链表中添加Fragment数据
        mFragmentList.add(new FirstFragment());
        mFragmentList.add(new FirstFragment());
        mFragmentList.add(new FirstFragment());

        //向Title数组链表中添加字符串数据
        mTitle.add("标题1");
        mTitle.add("标题2");
        mTitle.add("标题3");

        //初始化适配器
        FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager()) {

            //获取页面的数量
            @Override
            public int getCount() {
                return mFragmentList.size();
            }

            //返回指定页面的Fragment
            @Override
            public Fragment getItem(int position) {
                return mFragmentList.get(position);
            }

            //返回指定页面的标题
            @Override
            public CharSequence getPageTitle(int position) {
                return mTitle.get(position);
            }
        };

        //为ViewPager
        mViewPager.setAdapter(adapter);

        //将ViewPager和TabLayout关联绑定起来
        mTabLayout.setupWithViewPager(mViewPager);
    }


}

三.TabLayout+Fragment+ViewPager2+FragmentStateAdapter:

        复用的代码这里就不一一列举了,以下描述不一样的部分。

1.依赖包的导入:

        虽然我的本地环境发现没有引入ViewPager2依赖包也是可以引入ViewPager2的,但是这里也给大家列举出来了。

    //添加ViewPager2依赖包
    implementation 'androidx.viewpager2:viewpager2:1.0.0'

2.Acticity的布局文件:

        下面代码和前面的代码几乎是一样的,只是将引入ViewPager改成了引入ViewPager2。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="@+id/tab_layout"
        app:layout_constraintTop_toBottomOf="@id/tab_layout" />

</androidx.constraintlayout.widget.ConstraintLayout>

3.Activity的类文件:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import com.example.myapplication.fragment.FirstFragment;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    private ViewPager2 mViewPager2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTabLayout = findViewById(R.id.tab_layout);
        mViewPager2 = findViewById(R.id.viewpager2);
        initData();
    }

    private void initData() {

        //创建数组链表
        ArrayList<Fragment> mFragmentList = new ArrayList<>();
        ArrayList<String> mTitle = new ArrayList<>();

        //向Fragment数组链表中添加Fragment数据
        mFragmentList.add(new FirstFragment());
        mFragmentList.add(new FirstFragment());
        mFragmentList.add(new FirstFragment());

        //向Title数组链表中添加字符串数据
        mTitle.add("标题1");
        mTitle.add("标题2");
        mTitle.add("标题3");


        //实例化适配器
        MyAdapter myAdapter=new MyAdapter(getSupportFragmentManager(),getLifecycle(),mFragmentList);

        //设置适配器
        mViewPager2.setAdapter(myAdapter);

        //TabLayout和Viewpager2进行关联
        new TabLayoutMediator(mTabLayout, mViewPager2, new TabLayoutMediator.TabConfigurationStrategy() {

            @Override
            public void onConfigureTab(TabLayout.Tab tab, int position) {
                tab.setText(mTitle.get(position));
            }
        }).attach();


    //适配器内部类
    public class MyAdapter extends FragmentStateAdapter {
        List<Fragment> mFragmentList;
        public MyAdapter(FragmentManager fragmentManager,Lifecycle lifecycle, List<Fragment> fragments) {
            super(fragmentManager, lifecycle);
            mFragmentList = fragments;
        }


        //返回特定页面的Fragment
        @Override
        public Fragment createFragment(int position) {
            return mFragmentList.get(position);
        }

        //获取页面的数量
        @Override
        public int getItemCount() {
            return mFragmentList.size();
        }

    }


}

        最后实现的效果可以点击标题进行页面的切换,可以在Fragment所绘制的区域滑动进行页面的切换,但是无法在其它的空白区域滑动进行页面的切换。

                                       

        上面我们看的不是很清楚在哪块区域可以滑动,为此我们在Activity的布局文件将ViewPager2的背景设置为黑色,即添加如下:

android:background="@color/black"

        最后程序运行的效果如下,其中黑色的区域就是可以滑动的区域,其它的区域是不可滑动的。

        后来我发现问题出在Activity的布局文件中,对于ViewPager2的高度的设置为wrap_content,就会出现以上的问题,只需要设置为match_parent,即可在所有的区域都能实现滑动的效果。但是这个时候点击标题的时候就不会出现页面滑动的效果,因为这个时候整个区域都是Fragment的一部分。

                                        

        这时候大家可能会想为什么上面使用ViewPager的时候就不会出现上述的问题,那就让我们一起探索一下吧!我们将Activity的布局文件中的ViewPager的高度设置为wrap_content,并且背景设置为黑色,结果出现的布局如下:

                                        

        这可能就是ViewPager和ViewPager2的区别吧,这里面的Fragment绘制区域是除了标题栏的剩下所有区域,而不是ViewPager2的一小部分区域。去掉黑色背景,最后程序运行的结果如下:

                                        

        这里既可以实现点击标题切换页面,也可以实现在标题之外的其它区域 滑动进行页面的切换。

        设置为match_parent的时候结果类似,这里就不做描述了,只是点击标题没有页面切换的效果罢了。​​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值