TabLayoutを使った完成イメージは以下のようになります。

2つのタブを切り替えて、それぞれに異なるデータを表示させます。

実装はGitHubにアップしています。

https://github.com/highcom/ComicMemo

また、androidアプリ「巻数メモ」で実際の動作も確認できるので、利用してみて下さい。

 

 

クラス図は以下のようになります。

この中のクラスで注目したいのが

・ComicMemo

・SectionPagerAdapter

・PlaceholderFragment

です。では、これからレイアウトファイルと絡めて説明していきます。

 

1.activity.xmlとfragment.xmlを用意する

今回はメインのActivityとなるactivity_comic_memo.xmlは以下。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.design.widget.TabLayout
            android:id="@+id/itemtabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/blue"
            style="@style/ComicTabStyle" />

        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    </LinearLayout>
</RelativeLayout>

各ページのレイアウトを表示するFragmentとなるfragment_comic_memo.xmlは以下。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/comicListView"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"/>

</RelativeLayout>

TabLayoutがタブ自体の表示を担い、ViewPagerがページの内容を表示するfragment_comic_memo.xmlをバインドします。

 

2.FragmentActivityを継承したメイン画面の実装

メイン画面となるComicMemo.javaの実装

ViewPagerでFragmentをバインドするためのsectionPagerAdapter.javaの実装

で注目箇所は以下。


public class ComicMemo extends FragmentActivity {
    private SectionsPagerAdapter sectionsPagerAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_comic_memo);

        sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
        ViewPager viewPager = findViewById(R.id.view_pager);
        viewPager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = findViewById(R.id.itemtabs);
        tabs.setupWithViewPager(viewPager);
    }
}

public class SectionsPagerAdapter extends FragmentPagerAdapter {

    @StringRes
    private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2};
    private final Context mContext;
    private List fragmentList;
    private Fragment mCurrentFragment;

    public SectionsPagerAdapter(Context context, FragmentManager fm) {
        super(fm);
        mContext = context;
        fragmentList = new ArrayList();
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        Fragment fragment = PlaceholderFragment.newInstance(position);
        fragmentList.add(fragment);
        return fragment;
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return mContext.getResources().getString(TAB_TITLES[position]);
    }

    @Override
    public int getCount() {
        // Show 2 total pages.
        return 2;
    }
}

ComicMemoクラスで、SectionsPagerAdapterをインスタンス化し、ViewPagerクラスのAdapterとしてセットしてインスタンス化されます。

TabLayoutクラスをインスタンス化した後、ViewPagerをセットアップします。

その際に、SectionsPagerAdapterのgetItemメソッドが呼ばれます。このメソッドは作成するタブの数分呼ばれるので、今回は2回呼ばれます。

このメソッドの中で、それぞれのページの表示レイアウトとなるPlaceholderFragmentクラスのインスタンスが2つ作成されます。

 

3.各ページの画面となるFragmentの実装

Fragmentクラスを継承したPlaceholderFragmentクラスの実装は以下。


public class PlaceholderFragment extends Fragment {
    public static PlaceholderFragment newInstance(int index) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        return fragment;
    }

    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_comic_memo, container, false);
        return root;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        // ここから本来の処理を実装
    }
}

newInstanceメソッドが自分自身をインスタンス化して返すstaticなメソッドとなります。

onCreateViewで、レイアウトファイルとなるfragment_comic_memo.xmlをinflateします。

そして、この画面で実装したかったことは、onViewCreatedメソッドに書いていきます。通常のActivityでは、主にonCreateメソッドに書くような内容の部分になります。

onViewCreatedメソッド以降の実装は、以前のブログ「[Java]ListViewからRecyclerViewに変更して並べ替えを実装」でRecyclerViewを利用した実装例を書いていますので、ぜひこちらのブログも参考にしてみてください。

 
最後に2つアプリの紹介です。
パスコードロック付きのパスワード管理アプリ「パスワードメモ」の無料のアプリをGoogle Playで公開していますので、パスワードの管理に困っている方であれば是非利用してみて下さい。

 

やることを何行でも書ける、ToDoを作成した日、完了した日などの記録が残るToDoリストのアプリも無料で公開していますので是非こちらも利用してみてください。