Android开发——ViewPage与TabLayout和BottomNavigationView

本篇文章是接上一篇文章 Android开发——ViewPage的使用,使用了其中的例子。

谷歌设计TabLayout的本意是用来实现顶部菜单的,但是也可以作为底部菜单来使用,而BottomNavigationView基本上只能用来作为底部菜单使用。本篇文章就是介绍ViewPage和这两种控件的组合使用。

一、ViewPage和TabLayout

1.TabLayout作为顶部菜单

这里写图片描述

在上一篇文章中我们使用fragment和ViewPage实现侧滑菜单,现在只需要在布局文件中加入TabLayout然后把TabLayout和ViewPage联系在一起就可以了。

首先修改主布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    tools:context="com.example.test.MainActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginTop="0dp"
        android:background="#1FBCD2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:tabIndicatorColor="#ff0000"
        app:tabMode="fixed"
        app:tabGravity="fill"
        app:tabSelectedTextColor="#FFFFFF"
        app:tabTextColor="#000000"></android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPage"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="0dp"
        android:layout_marginTop="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tabs"
        app:layout_constraintVertical_bias="0.0"></android.support.v4.view.ViewPager>

</android.support.constraint.ConstraintLayout>

很好理解,只是在ViewPage上添加了一个TabLayout。

  • app:tabBackground:TabLayout的背景颜色
  • app:tabIndicatorColor:菜单指示器的颜色
  • app:tabSelectedTextColor:菜单选中时的颜色
  • app:tabTextColor:菜单未选中时的颜色

    下面介绍TabLayout的两个重要属性:

  • app:tabMode:有两个可选选项,分别是fixed和scrollable

  • app:tabGravity:有两个可选选项,分别是fill和center

当app:tabMode设置值scrollable表示此TabLayout中当子view超出屏幕边界时候,将提供滑动以便滑出不可见的那些子view。

这里列举两种常见的情况:

  • 菜单项很多:app:tabMode设置为scrollable,app:tabGravity设置为center
  • 菜单项很少:app:tabMode设置为fixed,app:tabGravity设置为fill

这里给出一张图解释他们的具体区别:
这里写图片描述

修改MainActivity中的代码:

package com.example.test;

import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

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

public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;  //对应的viewPager
    private List<TabLayout.Tab> tabList;
    private TabLayout tabLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (ViewPager) findViewById(R.id.viewPage);
        tabLayout = (TabLayout) findViewById(R.id.tabs);

        tabList = new ArrayList<>();
        ViewPageFragmentAdapter adapter = new ViewPageFragmentAdapter(getSupportFragmentManager());
        adapter.addFragment(new Fragment1());
        adapter.addFragment(new Fragment2());
        adapter.addFragment(new Fragment3());
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);
        tabList.add(tabLayout.getTabAt(0));
        tabList.add(tabLayout.getTabAt(1));
        tabList.add(tabLayout.getTabAt(2));
        tabList.get(0).setText("标签一");
        tabList.get(1).setText("标签二");
        tabList.get(2).setText("标签三");
    }
}

首先通过tabLayout的setupWithViewPager()方法与ViewPage设置联系,然后通过List< TabLayout.Tab >添加菜单项并设置标题。

2.TabLayout作为底部菜单

其实TabLayout作为底部菜单就是把TabLayout放在布局的底部,但是底部菜单一般都是图片加文字的组合,TabLayout也可以进行这样的设置。为了方便我们使用之前的布局,在布局底部再添加一个TabLayout。
这里写图片描述

修改主布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    tools:context="com.example.test.MainActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginTop="0dp"
        app:tabBackground="@color/colorAccent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:tabIndicatorColor="#fff"
        app:tabMode="fixed"
        app:tabGravity="fill"
        app:tabSelectedTextColor="#FFFFFF"
        app:tabTextColor="#000000"></android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPage"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="0dp"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tabs"
        android:layout_marginBottom="0dp"
        app:layout_constraintBottom_toTopOf="@+id/bottom_tabs"></android.support.v4.view.ViewPager>

    <android.support.design.widget.TabLayout
        android:id="@+id/bottom_tabs"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginBottom="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:tabBackground="@color/colorAccent"
        app:tabGravity="fill"
        app:tabIndicatorHeight="0dp"
        app:tabMode="fixed"
        app:tabSelectedTextColor="#FFFFFF"
        app:tabTextColor="#000000"></android.support.design.widget.TabLayout>
</android.support.constraint.ConstraintLayout>

只是在底部添加了一个TabLayout,注意底部菜单一般是没有指示条的,所以添加一个属性 app:tabIndicatorHeight=”0dp”将指示条高度设置为0,也就是隐藏。

修改MainActivity中的代码:

package com.example.test;

import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

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

public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;  //对应的viewPager
    private List<TabLayout.Tab> tabList;
    private TabLayout tabLayout;

    private List<TabLayout.Tab> tabList2;
    private TabLayout tabLayout2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (ViewPager) findViewById(R.id.viewPage);

        //顶部菜单
        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabList = new ArrayList<>();
        ViewPageFragmentAdapter adapter = new ViewPageFragmentAdapter(getSupportFragmentManager());
        adapter.addFragment(new Fragment1());
        adapter.addFragment(new Fragment2());
        adapter.addFragment(new Fragment3());
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);
        tabList.add(tabLayout.getTabAt(0));
        tabList.add(tabLayout.getTabAt(1));
        tabList.add(tabLayout.getTabAt(2));
        tabList.get(0).setText("标签一");
        tabList.get(1).setText("标签二");
        tabList.get(2).setText("标签三");

        //底部菜单
        tabLayout2 = (TabLayout) findViewById(R.id.bottom_tabs);
        tabList2 = new ArrayList<>();
        tabLayout2.setupWithViewPager(viewPager);
        tabList2.add(tabLayout2.getTabAt(0));
        tabList2.add(tabLayout2.getTabAt(1));
        tabList2.add(tabLayout2.getTabAt(2));
        tabList2.get(0).setText("标签一").setIcon(R.mipmap.ic_launcher);
        tabList2.get(1).setText("标签二").setIcon(R.mipmap.ic_launcher);
        tabList2.get(2).setText("标签三").setIcon(R.mipmap.ic_launcher);
    }
}

这里只是把TabLayout复制了一份,同样把他和ViewPage建立联系,注意我们在设置标签后添加了一项setIcon,设置图标,这是顶部菜单和底部菜单的主要区别。
到这里ViewPage和TabLayout的使用就介绍完了。

二、ViewPage和BottomNavigationView

在本例中我们仍然使用以前的ViewPage的布局和适配器。
这里写图片描述

1.首先新建一个布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.test.MainActivity2">

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPage"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="0dp"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginBottom="0dp"
        app:layout_constraintBottom_toTopOf="@+id/navigation"></android.support.v4.view.ViewPager>

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginBottom="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.896"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/navigation" />

</android.support.constraint.ConstraintLayout>

布局只有两个控件,底部是一个BottomNavigationView,内容是一个ViewPage。

2.BottomNavigationView的底部导航栏

app:menu=”@menu/navigation”这个属性就是给导航栏设置菜单项,这个和我们在标题栏上放设置菜单项的原理是一样的。在menu文件夹下(如果你的工程没有这个文件夹,就建一个)新建navigation.xml,在里面写要展示的菜单项,先看一下代码:
navigation.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_chat_black_24dp"
        android:title="@string/title_home" />

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_mms_black_24dp"
        android:title="@string/title_dashboard" />

    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications" />

</menu>

这里设置了三个菜单项,注意我使用的是矢量图,icon代表菜单项图标,title菜单项文字。

3.新建一个Activity

package com.example.test;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity2 extends AppCompatActivity {
    private ViewPager viewPager;
    private MenuItem menuItem;
    private BottomNavigationView bottomNavigationView;

    //BottomNavigationView的监听事件
    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    //点击菜单项时跳转ViewPage
                    viewPager.setCurrentItem(0);
                    return true;
                case R.id.navigation_dashboard:
                    viewPager.setCurrentItem(1);
                    return true;
                case R.id.navigation_notifications:
                    viewPager.setCurrentItem(2);
                    return true;
            }
            return false;
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        viewPager = (ViewPager) findViewById(R.id.viewPage);
        bottomNavigationView= (BottomNavigationView) findViewById(R.id.navigation);
        bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
        ViewPageFragmentAdapter adapter = new ViewPageFragmentAdapter(getSupportFragmentManager());
        adapter.addFragment(new Fragment1());
        adapter.addFragment(new Fragment2());
        adapter.addFragment(new Fragment3());
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                // 将当前的页面对应的底部标签设为选中状态
                if (menuItem != null) {
                    menuItem.setChecked(false);
                } else {
                    bottomNavigationView.getMenu().getItem(0).setChecked(false);
                }
                menuItem = bottomNavigationView.getMenu().getItem(position);
                menuItem.setChecked(true);
            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

        //禁止ViewPager滑动
//        viewPager.setOnTouchListener(new View.OnTouchListener() {
//            @Override
//            public boolean onTouch(View v, MotionEvent event) {
//                return true;
//            }
//        });
    }

}

上面的代码很简单,注释已经说的很清楚了,主要就是BottomNavigationView 和ViewPage的监听,当点击BottomNavigationView 时跳转ViewPage页面,当滑动ViewPage时跳转BottomNavigationView 。

这样就完成了一个简单的 BottomNavigationView 控件。该控件有几个地方需要注意的:

底部导航栏高度默认是 56dp。
菜单元素只能是 3~5 个。如果个数少于3个或者多于5个,则会报错。
icon 的选中颜色默认是 @color/colorPrimary。当然你也可以使用 app:itemIconTint=”@android:color/white” 来自定义,这样定以后,所有的 icon 颜色都是这个了。
菜单元素文字的默认颜色是 @color/colorPrimary。你可以使用 app:itemTextColor=”@android:color/white” 自定义。
底部导航栏背景颜色默认是当前样式的背景色(白色/黑色),你可以使用 app:itemBackground=”@android:color/black” 来更改。

关于BottomNavigationView 大于三个时的显示效果的调整等信息参照下面的文章:
http://blog.csdn.net/xiaoyangsavvy/article/details/70213537
http://blog.csdn.net/iwanttohitren/article/details/64537087

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值