LoginSignup
14
15

More than 5 years have passed since last update.

BottomNavigationViewとTablayout+ViewPagerを関連付ける.(メモ)

Posted at

はじめに

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

device.gif

参考

今回のBottomNavigationViewのライブラリ
https://github.com/sephiroth74/Material-BottomNavigation

BottomNavigationViewとTablayout+ViewPagerの結合
https://medium.com/@maydin/nested-viewpager-in-bottomnavigationview-a384b7068e92

実装

build.gradle

build.gradle(app)
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)を定義します.

menu/navigation.xml
<?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画面

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: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です.

つぎに本文です.

MainActivity.java
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つめのボタン

FirstFragment.java
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);
    }
}
fragment_first.xml
<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つめのボタン

SecondFragment.java
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);
    }
}
fragment_second.xml
<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を実装します.

ViewPagerFragment.java
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を定義します.

fragment_view_pager.xml
<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つめ

Fragment1.java
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);
    }
}
fragment_fragment1.xml
<?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つめ

Fragment2.java
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);
    }
}
fragment_fragment1.xml
<?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を新たに関連付けるのに本当に苦戦しました...
アプリを作成していく上では一回全体像を把握した方がいいですね(わかりきったことですが...):cloud::disappointed_relieved:

今回のコードの全貌です!
https://github.com/hisakioomae/BottomNavigationView_Nested_Viewpager
最後までお付き合いいただきありがとうございました.

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15