はじめに
BottomNavigationViewとTablayoutを組み合わせたサンプルを置いておきます.
こういう機能を実装したアプリはよく見かけるので参考になれば幸いです.

参考
今回のBottomNavigationViewのライブラリ
https://github.com/sephiroth74/Material-BottomNavigation
BottomNavigationViewとTablayout+ViewPagerの結合
https://medium.com/@maydin/nested-viewpager-in-bottomnavigationview-a384b7068e92
実装
build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:support-vector-drawable:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
testCompile 'junit:junit:4.12'
compile 'it.sephiroth.android.library.bottomnavigation:bottom-navigation:2.0.1-rc1'
}
BottomNavigationView
今回はライブラリを用いさせていただきました.
デザインがかわいらしいですね!
まず,BottomNavigationViewのアイコンやら(menu)を定義します.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:bbn_rippleColor="#33ffffff"
app:bbn_badgeColor="#FFFF0000">
<item
android:color="@color/colorPrimary"
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:color="@android:color/holo_green_dark"
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:color="@android:color/holo_orange_dark"
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
</menu>
載せるアイコンは何でもいいですが,今回はdrawable以下に配置しています.
以下のサイトはIconがいっぱいあります.
Material Design Icons
https://materialdesignicons.com/icon/fire
これで,BottomNavigationViewの設定は出来ました.
次はこれをMain画面に配置しましょう.
Main画面
<?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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.bnviewpager.viewpageriteminbnv.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/navigation" />
<it.sephiroth.android.library.bottomnavigation.BottomNavigation
app:bbn_badgeProvider="@string/bbn_badgeProvider"
app:layout_behavior="@string/bbn_phone_view_behavior"
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:bbn_entries="@menu/navigation" />
</RelativeLayout>
</LinearLayout>
it.sephiroth.android.library.bottomnavigation.BottomNavigation
が今回利用するBottomNavigationViewです.
つぎに本文です.
package com.bnviewpager.viewpageriteminbnv;
import android.os.Bundle;
import android.support.annotation.IdRes;
import it.sephiroth.android.library.bottomnavigation.BottomNavigation;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private BottomNavigation BottomNavigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView = (BottomNavigation) findViewById(R.id.navigation);
BottomNavigationView.setOnMenuItemClickListener(new BottomNavigation.OnMenuItemSelectionListener() {
@Override
public void onMenuItemSelect(@IdRes int i, int i1, boolean b) {
switch (i1) {
case 0:
replaceFragment(FirstFragment.newInstance());//Fragmentを入れ替える
break;
case 1:
replaceFragment(SecondFragment.newInstance());//Fragmentを入れ替える
break;
case 2:
replaceFragment(ViewPagerFragment.newInstance());//Fragmentを入れ替える
break;
}
}
@Override
public void onMenuItemReselect(@IdRes int i, int i1, boolean b) {
}
});
addFragment(FirstFragment.newInstance());//最初はadd
}
private void addFragment(Fragment newFragment){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragment_container, newFragment).commit();
}
private void replaceFragment(Fragment newFragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, newFragment).commit();//R.id.fragment_containerのを代える
}
}
BottomNavigationViewが押されたらFragmentを交換します.
このMainが一番重要です.
後はFragmentを結びつけるだけです.
replaceするFragmentを以下に示します.
BottomNavigationView 1つめのボタン
package com.bnviewpager.viewpageriteminbnv;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FirstFragment extends Fragment {
public static FirstFragment newInstance() {
FirstFragment fragment = new FirstFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_first, container, false);
}
}
<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="com.bnviewpager.viewpageriteminbnv.FirstFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Home" />
</FrameLayout>
BottomNavigationView 2つめのボタン
package com.bnviewpager.viewpageriteminbnv;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SecondFragment extends Fragment {
public static SecondFragment newInstance() {
SecondFragment fragment = new SecondFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_second, container, false);
}
}
<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="com.bnviewpager.viewpageriteminbnv.SecondFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Dashboard" />
</FrameLayout>
BottomNavigationView 3つめのボタン
ここでは,Fragmentの中にtablayoutとviewpagerを実装します.
package com.bnviewpager.viewpageriteminbnv;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ViewPagerFragment extends Fragment {
ViewPager viewPager;
ViewPagerAdapter viewPagerAdapter;
public static ViewPagerFragment newInstance() {
ViewPagerFragment fragment = new ViewPagerFragment();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view_pager, container, false);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(viewPagerAdapter);
return view;
}
public static class ViewPagerAdapter extends FragmentStatePagerAdapter {
private static final int NUM_ITEMS = 2;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
if(position == 0){
return Fragment1.newInstance();
}
else {
return Fragment2.newInstance();
}
}
@Override
public CharSequence getPageTitle(int position) {
if(position == 0){
return "flagment1";
}
else {
return "flagment2";
}
}
}
}
tablayoutとviewpagerを定義します.
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#EEEEEE"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
今回はtab2つです.
次に,tablayoutと結びつけるFragmentです.
tab 1つめ
package com.bnviewpager.viewpageriteminbnv;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
public static Fragment1 newInstance() {
Fragment1 fragment = new Fragment1();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_fragment1, container, false);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment1" />
</LinearLayout>
tab 2つめ
package com.bnviewpager.viewpageriteminbnv;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
public static Fragment2 newInstance() {
Fragment2 fragment = new Fragment2();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_fragment2, container, false);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment2" />
</LinearLayout>
以上です.
おわりに
Tablayoutを全て実装終えてから,親要素?のBottomNavigationViewを新たに関連付けるのに本当に苦戦しました...
アプリを作成していく上では一回全体像を把握した方がいいですね(わかりきったことですが...)
今回のコードの全貌です!
https://github.com/hisakioomae/BottomNavigationView_Nested_Viewpager
最後までお付き合いいただきありがとうございました.