android使用Viewpager和TabLayout结合fragment实现首页底部导航的效果

前言

现如今几乎每一款手机APP首页都采用了底部导航的功能,现在我们使用Viewpager和TabLayout结合fragment来实现该功能。

效果图如下:

这里有一个问题,TabLayout的五个icon在模拟器中宽度无法充满屏幕,暂时还不知道为什么,手机能够正常显示。

该项目的githup地址为:https://github.com/gumaoqi/bottomNavigation

你可以去将项目clone下来,然后查看或更改来达到自己的需求。

具体代码:

build.gradle


implementation 'com.jakewharton:butterknife:8.8.1'
//butterknife
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
//butterknife
implementation 'com.android.support:design:27.1.1'

项目中用到butterknife,添加依赖;TabLaout需要添加design的依赖,该依赖下还有经常用到的RecyclerView等控件

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.activity_main_back_tv)
    TextView activityMainBackTv;
    @BindView(R.id.activity_main_title_tv)
    TextView activityMainTitleTv;
    @BindView(R.id.activity_main_menu_tv)
    TextView activityMainMenuTv;
    @BindView(R.id.activity_main_fragment_vp)
    ViewPager activityMainFragmentVp;
    @BindView(R.id.activity_main_bottom_navigation_tl)
    TabLayout activityMainBottomNavigationTl;


    List<Fragment> fragmentList;
    List<String> stringList;
    MyFragmentPagerAdapter myFragmentPagerAdapter;

    void inidata() {
        fragmentList = new ArrayList<>();
        fragmentList.add(new MyFragment());
        fragmentList.add(new MyFragment());
        fragmentList.add(new MyFragment());
        fragmentList.add(new MyFragment());
        fragmentList.add(new MyFragment());
        stringList = new ArrayList<>();
        stringList.add("苹果");
        stringList.add("香蕉");
        stringList.add("菠萝");
        stringList.add("葡萄");
        stringList.add("西瓜");
        myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(), fragmentList, stringList);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        inidata();
        //设置viewpager和tablayout
        activityMainFragmentVp.setAdapter(myFragmentPagerAdapter);
        activityMainFragmentVp.setOffscreenPageLimit(5);
        activityMainBottomNavigationTl.setupWithViewPager(activityMainFragmentVp);
        for (int i = 0; i < activityMainBottomNavigationTl.getTabCount(); i++) {
            activityMainBottomNavigationTl.getTabAt(i).setIcon(R.mipmap.ic_launcher_round);
        }
        activityMainBottomNavigationTl.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                switch (tab.getPosition()) {
                    case 0:
                        activityMainTitleTv.setText("苹果");
                        break;
                    case 1:
                        activityMainTitleTv.setText("香蕉");
                        break;
                    case 2:
                        activityMainTitleTv.setText("菠萝");
                        break;
                    case 3:
                        activityMainTitleTv.setText("葡萄");
                        break;
                    case 4:
                        activityMainTitleTv.setText("西瓜");
                        break;
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }
}

一共设置了5个相同的fragment,实际项目中根据不同需求添加不同的fragment完成不同的功能

activity.main.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/turquoise"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/activity_main_back_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="返回" />

        <TextView
            android:id="@+id/activity_main_title_tv"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="苹果"
            android:textColor="@color/colorPrimary" />

        <TextView
            android:id="@+id/activity_main_menu_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="菜单" />
    </LinearLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/activity_main_fragment_vp"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"></android.support.v4.view.ViewPager>

    <android.support.design.widget.TabLayout
        android:id="@+id/activity_main_bottom_navigation_tl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"></android.support.design.widget.TabLayout>
</LinearLayout>

最上方有一个标题栏,实际项目中通常为toolbar,这里用LinearLayout代替

MyFragment.java


public class MyFragment extends Fragment {
    final String TAG = "MyFragment";
    private Unbinder unbinder;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_my, container, false);
        //返回一个Unbinder值(进行解绑),注意这里的this不能使用getActivity()
        unbinder = ButterKnife.bind(this, view);
        intData();
        setView();
        return view;

    }

    void intData() {

    }

    void setView() {

    }

    /**
     * onDestroyView中进行解绑操作
     */
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}

Myfragment不做任何事,仅仅是显示一个文字。

fragment_my.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">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="我是一个fragment" />
</LinearLayout>

布局也很简单,只有一个textview

至此,已成功实现了该功能,更多的后续功能需要实现各种Fragment去完成,其中涉及到Activity和Fragment的通信,Fragment之间的通信,但这些不是本文的内容,请自行学习。

后记

在使用Viewpager结合Fragment中你一定会遇到很多的坑,这里记录一个坑:Viewpager会默认预加载一个左右的Fragment,也就是说当我处于苹果Fragment的时候,香蕉Fragment其实已经被加载出来了;当我处于香蕉Fragment的时候,苹果Fragment和菠萝Fragment其实已经被加载出来了。我们可以通过setOffscreenPageLimit(int limit)调整这个预加载的数量,比如说:设置为5,就会预加载左右最多各5个一共最多10个Fragment,那么可以设置为0关闭预加载吗?答案是:不行。查看setOffscreenPageLimit(int limit)源码:


public void setOffscreenPageLimit(int limit) {
    if (limit < 1) {
        Log.w("ViewPager", "Requested offscreen page limit " + limit + " too small; defaulting to " + 1);
        limit = 1;
    }

    if (limit != this.mOffscreenPageLimit) {
        this.mOffscreenPageLimit = limit;
        this.populate();
    }

}

当你传入的数字小于1时,他会设为1,也就是说我们无法通过该手段关闭其预加载。

 

本篇文章的主要目的为:记录某个功能的实现方法,以便日后查询。如果阅读后对你有所帮助,我将深感荣幸。

博主水平有限,如有指正错误和其他建议请在评论区留言。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值