ViewPager和Fragment使用(附源码)

目录

1 初级版

1.1 XML布局文件添加ViewPager

1.2 Java代码创建Adapter类

1.2.1 重写方法getItem

1.2.2 重写方法getCount

1.2.3 适配器构造器

1.3 创建Fragment

1.4 Java主代码

1.4.1 数据源添加数据

1.4.2实例化适配器

1.4.3给ViewPager添加适配器

1.4.4 给ViewPager添加监听事件

2 中级版 

2.1 XML布局文件添加ViewPager

2.2 Java代码创建Adapter类

2.3 重写FragmentPagerAdapter的两个方法

2.4 创建Fragment

2.5 Java主代码

2.5.1 数据源添加数据

2.5.2 实例化适配器

2.5.3 给ViewPager添加适配器

2.6 ViewPager和底部导航栏的联动

3 高级版

3.1 ViewPager用法

3.2 FragmentPagerAdapter用法

3.3 ButtonNavigationView用法

3.4 ViewPager切换页面和ButtonNavigationView的联动

3.4.1 ViewPager联动ButtonNavigationView

3.4.2 ButtonNavigationView联动ViewPager

3.4.3 Badge用法(新消息提示)

3.5

3.6 创建菜单menu

3.7 XML布局文件添加ViewPager和ButtonNavigationView

3.8 Java主代码获取控件

3.9 Java代码创建Adapter类

3.10 重写FragmentPagerAdapter的两个方法

3.11 适配器构造器

3.12 创建Fragment

3.12.1 XML文件

3.12.2 Java文件

3.13 Java主代码

3.13.1 数据源添加数据

3.13.2 实例化适配器

3.13.3 给ViewPager添加适配器

3.13.4 给ViewPager添加监听事件

3.13.5 给ButtonNavigationView添加监听事件

3.14 Badge的设置

3.14.1 Badge的添加

3.14.2 Badge的移除

最后,上Activity的主代码~


1 初级版

ViewPager通过滑动来切换Fragment,无底部导航栏。

用法:数据List<Fragment>+适配器FragmentPagerAdapter+ViewPager

通过FragmentPagerAdapter连接两者的桥梁,里面需要重写两个方法getItem,getCount。

第一个方法是获取一个Fragment,从数据源获取。

第二个方法是获取数据源的大小,也就是有几页。

1.1 XML布局文件添加ViewPager

在Activity的XML布局文件中添加一个控件——ViewPager。

加入宽高和ID即可。

在Java代码中找控件ViewPager。


1.2 Java代码创建Adapter类

继承自FragmentPagerAdapter类,重写两个方法getItem,getCount。

public class MyFragmentVPAdapter extends FragmentPagerAdapter {
    private List<Fragment> fragmentList;

    public MyFragmentVPAdapter(@NonNull FragmentManager fm,List<Fragment> list) {
        super(fm);
        this.fragmentList=list;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return fragmentList==null?null:fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList==null?0:fragmentList.size();
    }
}

1.2.1 重写方法getItem

获取数据源的位置

public Fragment getItem(int position){
    return mFragmentList==null?null:mFragmentList.get(position);
}

1.2.2 重写方法getCount

获取数据源的个数

public int getCount(){
    return mFragmentList==null?0:mFragmentList.size();
}

1.2.3 适配器构造器

需要传入一个FragmentManager对象和数据源。


1.3 创建Fragment

也是只有一个文本TextView,new的时候传入一个参数来更改文本。


1.4 Java主代码

声明数据源List<Fragment>,实例化适配器。

1.4.1 数据源添加数据

实例化Fragment,用newInstance()。并add到List中。

1.4.2实例化适配器

传入两个参数,getSupportFragmentManager()即可获取FragmentManager对象,数据源。

1.4.3给ViewPager添加适配器

setAdapter即可。

1.4.4 给ViewPager添加监听事件

addOnPageChangeListener(),其中可以设置比如让底部导航栏变色。


2 中级版 

ViewPager通过滑动来切换Fragment,有普通的底部导航栏,故也可以通过底部导航栏切换fragment。

用法:ViewPager+FragmentPagerAdapter+普通ButtonView

ViewPager用法+FragmentPagerAdapter的用法+ViewPager和底部导航栏的联动

就是要写很多控件,还要找,比较麻烦。

2.1 XML布局文件添加ViewPager

在Activity的XML布局文件中添加一个控件——ViewPager。

加入宽高和ID即可。

在Java代码中找控件ViewPager。


2.2 Java代码创建Adapter类

继承自FragmentPagerAdapter类,重写两个方法getItem,getCount。


2.3 重写FragmentPagerAdapter的两个方法

同上1.2。


2.4 创建Fragment

也是只有一个文本TextView,new的时候传入一个参数来更改文本。


2.5 Java主代码

声明数据源List<Fragment>,实例化适配器。

2.5.1 数据源添加数据

实例化Fragment,用newInstance()。并add到List中。

2.5.2 实例化适配器

传入两个参数,getSupportFragmentManager()即可获取FragmentManager对象,数据源。

2.5.3 给ViewPager添加适配器

setAdapter即可。


2.6 ViewPager和底部导航栏的联动

当切换页面的时候,把底部导航相应的状态给改变一下。通过ViewPager的addOnPageChangeListener的三个回调。

当点击底部导航时,把Fragment的页面给切换一下。通过线性布局的按钮点击事件的回调。


3 高级版

ViewPager通过滑动来切换Fragment,底部导航栏换成了ButtonNavigationView,故也可以通过底部导航栏切换fragment。

就是在中级版的基础上,把普通按钮换成了另外一个控件ButtonNavigationView,这个控件更加方便。

用法:ViewPager+FragmentPagerAdapter+ButtonNavigationView实现底部导航页

ViewPager用法+FragmentPagerAdapter用法+ButtonNavigationView用法+ViewPager切换页面和ButtonNavigationView的联动+Badge用法(新消息提示)

3.1 ViewPager用法

数据List<>+适配器FragmentPagerAdapter+ViewPager


3.2 FragmentPagerAdapter用法

继承自FragmentPagerAdapter类,重写两个方法getItem,getCount。

同上1.2。


3.3 ButtonNavigationView用法

有两个重要的属性app:menu(声明导航按钮)和app:labelVisibility(导航按钮的显示模式,有4个值可选)

labeled(一直显示文字),unlabeled(不显示文字),selected(选中显示文字),auto(自动:小于三个按钮取labeled;大于三个按钮取selected)。


3.4 ViewPager切换页面和ButtonNavigationView的联动

3.4.1 ViewPager联动ButtonNavigationView

当ViewPager发生变化时,底部按钮要发生变化

mViewPager.addOnPageChangeListener(...)

mBottomNavigationView.setSelectedItemId(R.id.menu_xxx)

3.4.2 ButtonNavigationView联动ViewPager

当点击按钮时,ViewPager要发生变化

mBottomNavigationView.setOnItemSelectedListener(...)

mViewPager.setCurrentItem(index)

3.4.3 Badge用法(新消息提示)

创建Badge

//新消息加到菜单中哪个icon中,注册
BadgeDrawable badge=mBottomNavigationView.getOrCreateBadge(R.id.menu_xxx);

设置消息数

//默认是4个字符,只能999+
badge.setNumber(949);
//代表只能容下3个字符,99+
//若是4,则是999+
badge.setMaxCharacterCount(3);

到达页面移除badge

mBottomNavigationView.removeBadge(R.id.menu_xxx);

开始写代码咯! 

3.5

3.6 创建菜单menu

之前的博客有写,直接创建选项菜单即可。可以在icon选取一个selected选择器,有按下和不按的两种图标状态。我这里没有设置选择器,只有一个icon而已。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/like"
        android:icon="@drawable/like"
        android:title="喜欢"/>
    <item android:id="@+id/local"
        android:icon="@drawable/local"
        android:title="定位"/>
    <item android:id="@+id/report"
        android:icon="@drawable/report"
        android:title="举报"/>
    <item android:id="@+id/share"
        android:icon="@drawable/share"
        android:title="分享"/>
</menu>

3.7 XML布局文件添加ViewPager和ButtonNavigationView

最基础的是设置宽高和Id,如果没有ButtonNavigationView控件,可能是没有导入依赖"com.google.android.material:material:1.2.1"。

ViewPager额外设置权重weight属性。

ButtonNavigationView额外设置app:menu和app:labelVisibility。

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

   <androidx.viewpager.widget.ViewPager
       android:id="@+id/vp"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_weight="1" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btm_nav"
        app:menu="@menu/btm_menu"
        app:labelVisibilityMode="labeled"/>
</LinearLayout>

3.8 Java主代码获取控件

找两个控件即可。

public class MainActivity extends AppCompatActivity {
    private ViewPager viewPager;
    private BottomNavigationView mBottomNavigationView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mBottomNavigationView = findViewById(R.id.btm_nav);
        viewPager = findViewById(R.id.vp);
    }
}

3.9 Java代码创建Adapter类

继承自FragmentStatePagerAdapter类,这个类会回收划掉的页面,而前面那个FragmentPagerAdapter不会回收,会在后台占据着内存,使用方面是一样的。

3.10 重写FragmentPagerAdapter的两个方法

重写getItem,getCount。同上1.2。

3.11 适配器构造器

设置一个传入FragmentManager对象和数据源的构造器。


3.12 创建Fragment

3.12.1 XML文件

也是只有一个文本TextView,new的时候传入一个参数来更改文本。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".viewPagerFragment">

    <TextView
        android:id="@+id/tv_1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="25dp"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

3.12.2 Java文件

通过传入参数来更改文本

public class viewPagerFragment extends Fragment {

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private String mParam1;
    private String mParam2;
    private TextView textView;

    public viewPagerFragment() {
    }

    public static viewPagerFragment newInstance(String param1, String param2) {
        viewPagerFragment fragment = new viewPagerFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_view_pager, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view,
                              @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        textView= view.findViewById(R.id.tv_1);
        if(TextUtils.isEmpty(mParam1)){
            textView.setText(mParam1);
        }
    }
}

3.13 Java主代码

声明数据源List<Fragment>,实例化适配器。

List<Fragment> list=new ArrayList<>();

3.13.1 数据源添加数据

实例化Fragment,用newInstance()。并add到List中。

private void initData() {
        viewPagerFragment viewPagerFragmenthome=viewPagerFragment.newInstance("首页","");
        viewPagerFragment viewPagerFragmentfind=viewPagerFragment.newInstance("发现","");
        viewPagerFragment viewPagerFragmentmine=viewPagerFragment.newInstance("我的","");
        
        list.add(viewPagerFragmenthome);
        list.add(viewPagerFragmentfind);
        list.add(viewPagerFragmentmine);
    }

3.13.2 实例化适配器

传入两个参数,getSupportFragmentManager()即可获取FragmentManager对象,数据源。

myFragmentVPAdapter = new MyFragmentVPAdapter(getSupportFragmentManager(), list);

3.13.3 给ViewPager添加适配器

setAdapter即可。

viewPager.setAdapter(myFragmentVPAdapter);

3.13.4 给ViewPager添加监听事件

addOnPageChangeListener(),其中可以设置比如让底部导航栏变色。


mViewPager.addOnPageChangeListener(...)
 
mBottomNavigationView.setSelectedItemId(R.id.menu_xxx)
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                switch(position){
                    case 0:
                        mBottomNavigationView.setSelectedItemId(R.id.like);
                        break;
                    case 1:
                        mBottomNavigationView.setSelectedItemId(R.id.local);
                        break;
                    case 2:
                        mBottomNavigationView.setSelectedItemId(R.id.report);
                        break;
                    case 3:
                        mBottomNavigationView.setSelectedItemId(R.id.share);
                        break;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

 写在第二个回调onPageSelected(),然后设置某个icon被选中即可,不需要再取消其他icon的选中状态,这个控件选中其中一个,另外的icon就会被取消,这就是ButtonNavigationView的好处

3.13.5 给ButtonNavigationView添加监听事件

mBottomNavigationView.setOnItemSelectedListener(),可以让ViewPager切换页面。

//旧方法,已经废弃
mBottomNavigationView.setOnItemSelectedListener(...)
//设置ViewPager
mViewPager.setCurrentItem(index)
//我们这里不用废弃的旧方法,用setOnItemSelectedListener
mBottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch(item.getItemId()){
                    case R.id.like:
                        viewPager.setCurrentItem(0);
                        break;
                    case R.id.local:
                        viewPager.setCurrentItem(1);
                        break;
                    case R.id.report:
                        viewPager.setCurrentItem(2);
                        break;
                    case R.id.share:
                        viewPager.setCurrentItem(3);
                        break;
                    default:
                        break;
                }
                return true;
            }
        });

3.14 Badge的设置

3.14.1 Badge的添加

BadgeDrawable badgeDrawable=mBottomNavigationView.getOrCreateBadge(R.id.like);
        badgeDrawable.setNumber(888);
        badgeDrawable.setMaxCharacterCount(3);

3.14.2 Badge的移除

在ViewPager的页面监听事件中获取信息,如果到达这个页面的话就移除。

mBottomNavigationView.removeBadge(R.id.like);

最后,上Activity的主代码~

package com.example.fragmentviewpager;

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

import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;

import com.google.android.material.badge.BadgeDrawable;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private ViewPager viewPager;
    private BottomNavigationView mBottomNavigationView;
    private MyFragmentVPAdapter myFragmentVPAdapter;
    List<Fragment> list=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mBottomNavigationView = findViewById(R.id.btm_nav);
        viewPager = findViewById(R.id.vp);

        initData();

        myFragmentVPAdapter = new MyFragmentVPAdapter(getSupportFragmentManager(), list);

        viewPager.setAdapter(myFragmentVPAdapter);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                switch(position){
                    case 0:
                        mBottomNavigationView.removeBadge(R.id.like);
                        mBottomNavigationView.setSelectedItemId(R.id.like);
                        break;
                    case 1:
                        mBottomNavigationView.setSelectedItemId(R.id.local);
                        break;
                    case 2:
                        mBottomNavigationView.setSelectedItemId(R.id.report);
                        break;
                    case 3:
                        mBottomNavigationView.setSelectedItemId(R.id.share);
                        break;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        mBottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch(item.getItemId()){
                    case R.id.like:
                        viewPager.setCurrentItem(0);
                        break;
                    case R.id.local:
                        viewPager.setCurrentItem(1);
                        break;
                    case R.id.report:
                        viewPager.setCurrentItem(2);
                        break;
                    case R.id.share:
                        viewPager.setCurrentItem(3);
                        break;
                    default:
                        break;
                }
                return true;
            }
        });

        BadgeDrawable badgeDrawable=mBottomNavigationView.getOrCreateBadge(R.id.like);
        badgeDrawable.setNumber(888);
        badgeDrawable.setMaxCharacterCount(3);
    }

    private void initData() {
        viewPagerFragment viewPagerFragmenthome=viewPagerFragment.newInstance("首页","");
        viewPagerFragment viewPagerFragmentfind=viewPagerFragment.newInstance("发现","");
        viewPagerFragment viewPagerFragmentmine=viewPagerFragment.newInstance("我的","");

        list.add(viewPagerFragmenthome);
        list.add(viewPagerFragmentfind);
        list.add(viewPagerFragmentmine);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

七qi_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值