アンドロイドのTabLayoutとViewPager

このチュートリアルでは、既にこのチュートリアルで実装したTabLayoutの下にViewPagerを実装します。

AndroidのTabLayout ViewPagerの概要

ViewPagersはデータのページをスワイプするために使用されます。通常、フラグメントと一緒に使用されます。前のチュートリアルのレイアウトを以下のように変更しましょう。activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.scdev.tablayoutviewpager.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            style="@style/MyStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabGravity="fill"
            app:tabMode="fixed" />

    </android.support.design.widget.AppBarLayout>


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


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

MainActivityにViewPagerを追加する前に、アダプターの設定をしましょう。

public class ViewPagerAdapter extends FragmentPagerAdapter {

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = null;
        if (position == 0)
        {
            fragment = new FragmentA();
        }
        else if (position == 1)
        {
            fragment = new FragmentB();
        }
        else if (position == 2)
        {
            fragment = new FragmentC();
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return 3;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        String title = null;
        if (position == 0)
        {
            title = "Tab-1";
        }
        else if (position == 1)
        {
            title = "Tab-2";
        }
        else if (position == 2)
        {
            title = "Tab-3";
        }
        return title;
    }
}

上記のViewPagerAdapterはFragmentPagerAdapterを拡張しています。それは3つのフラグメントを呼び出し、各ページに1つのフラグメントを持っています。それぞれのフラグメントは、以下に示すようにfragment_list.xmlを持っています。

<?xml version="1.0" encoding="utf-8"?>

<ListView xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/list"/>

以下に、FragmentA(/B/C).javaのコードを示します。

public class FragmentA extends Fragment {


    ListView list;

    public FragmentA() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);

        list = (ListView) view.findViewById(R.id.list);
        ArrayList stringList= new ArrayList();

        stringList.add("Item 1A");
        stringList.add("Item 1B");
        stringList.add("Item 1C");
        stringList.add("Item 1D");
        stringList.add("Item 1E");
        stringList.add("Item 1F");
        stringList.add("Item 1G");
        stringList.add("Item 1H");
        stringList.add("Item 1I");
        stringList.add("Item 1J");
        stringList.add("Item 1K");
        stringList.add("Item 1L");
        stringList.add("Item 1M");
        stringList.add("Item 1N");
        stringList.add("Item 1O");
        stringList.add("Item 1P");
        stringList.add("Item 1Q");
        stringList.add("Item 1R");
        stringList.add("Item 1S");
        stringList.add("Item 1T");
        stringList.add("Item 1U");
        stringList.add("Item 1V");
        stringList.add("Item 1W");
        stringList.add("Item 1X");
        stringList.add("Item 1Y");
        stringList.add("Item 1Z");

        CustomAdapter adapter = new CustomAdapter(stringList,getActivity());
        list.setAdapter(adapter);

        return view;
    }
}

上記のListViewに対するCustomAdapter.javaクラスは次の通りです。 (Jōki no ListView ni taisuru CustomAdapter.java kurasu wa tsugi no tōri desu.)

public class CustomAdapter extends ArrayAdapter {

    private ArrayList dataSet;
    Context mContext;

    // View lookup cache
    private static class ViewHolder {
        TextView txtName;

    }

    public CustomAdapter(ArrayList data, Context context) {
        super(context, R.layout.row_item, data);
        this.dataSet = data;
        this.mContext = context;

    }

    @Nullable
    @Override
    public String getItem(int position) {
        return dataSet.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder; // view lookup cache stored in tag

        if (convertView == null) {

            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.row_item, parent, false);
            viewHolder.txtName = (TextView) convertView.findViewById(R.id.name);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.txtName.setText(getItem(position));
        // Return the completed view to render on screen
        return convertView;
    }
}

以下にMainActivity.javaクラスが示されています。

public class MainActivity extends AppCompatActivity {

    TabLayout tabLayout;
    ViewPager viewPager;
    ViewPagerAdapter viewPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        viewPager = (ViewPager) findViewById(R.id.viewPager);
        viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(viewPagerAdapter);
        tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
    }

}

上記のコードでは、setupWithViewPager()メソッドを使用して、TabLayoutとViewPagerを結び付けています。FragmentPagerAdapterのgetPageTitle()メソッドを使用して、各タブのタイトルを設定しています。上記のコードを実行した場合の出力を見てみましょう。質問:なぜToolBarが設定されたscrollFlagsに従ってスクロールしないのですか?それはListViewのせいです。CoordinatorLayoutはListViewをサポートしていません(Material Designの一部ではありません)し、スクロールのジェスチャーもサポートしていません。そのため、代わりにRecyclerViewを使用することを推奨しています。注意:CoordinatorLayoutのアクティビティに属するフラグメントは、スクロールのジェスチャーが正しく機能するようにするために、NestedScrollViewまたはRecyclerViewを親として使用する必要があります。アプリケーション内のListViewの実装を置き換える前に、現在のフラグメントのレイアウトを下記のようにNestedScrollViewで包みます。fragment_list.xml

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.NestedScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ListView xmlns:android="https://schemas.android.com/apk/res/android"
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.v4.widget.NestedScrollView>

さて、アプリケーションの挙動を確認してみましょう。おっと、スクロールは修正されましたが、ListViewは今は一行しか表示されません。したがって、私たちのマテリアルデザインのビュータイプではListViewは使用しない方が良いですね。さあ、アプリケーションを修正しましょう。

アンドロイドのTabLayout ViewPagerプロジェクトの構造。

AndroidのTabLayout ViewPagerの例のコード

以下はactivity_main.xml、MainActivity.java、ViewPagerAdapter.javaのクラスは変更されていません。では、フラグメントを見てみましょう。フラグメントのレイアウトは以下の通りです。fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="https://schemas.android.com/apk/res/android" />

以下にFragmentA(/B/C).javaが与えられています。

package com.scdev.tablayoutviewpager;


import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentA extends Fragment {

    RecyclerView recyclerView;

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

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        String[] items = getResources().getStringArray(R.array.tab_A);
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(items);
        recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);

    }
}

データを表示するために、strings.xmlファイルにデータを移動しました。そこでデータが定義されています。

<resources>
    <string name="app_name">TabLayoutViewPager</string>
    <string name="action_settings">Settings</string>

    <string-array name="tab_A">
        <item>Item 1A</item>
        <item>Item 1B</item>
    </string-array>

    <string-array name="tab_B">
        <item>Item 2A</item>
    </string-array>
</resources>

注意:私たちは、フラグメントのコードロジックを最適化しました。これにより、ビューが作成されると、アダプターにデータがセットされ、表示されるようになりました。RecyclerViewAdapter.javaには、文字列の配列が引数としてあります。そのコードは以下の通りです。

public class RecyclerViewAdapter extends RecyclerView.Adapter {

    String[] items;

    public RecyclerViewAdapter(String[] items) {
        this.items = items;
    }

    @Override
    public TextItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_list_item, parent, false);
        return new TextItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(TextItemViewHolder holder, int position) {
        holder.bind(items[position]);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return items.length;
    }
}

上記のコードでは、リストアイテムに似たレイアウトを持つカスタムRecyclerViewHolderクラスを追加しました。TextItemViewHolder.javaクラスは以下のようになります。

public class TextItemViewHolder extends RecyclerView.ViewHolder {
    private TextView textView;


    public TextItemViewHolder(View itemView) {
        super(itemView);
        textView = (TextView) itemView.findViewById(R.id.list_item);
    }

    public void bind(String text) {
        textView.setText(text);
    }

}

上記のカスタムViewHolderのレイアウトは、recycler_view_list_item.xmlです。 (Jouki no kasutamu ViewHolder no reirautto wa, recycler_view_list_item.xml desu.)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/list_item"
        android:textSize="18sp"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingRight="8dp"
        android:paddingLeft="8dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <View
        android:id="@+id/separator"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#858585" />
</LinearLayout>

アプリケーションの動作結果は以下のように表示されます。レイアウトの構造はWhatsAppアプリケーションに似ています。より似せるために、以下の変更を行ってください。

  • Import and add the two menu icon drawables
  • Inflate them in the MainActivity.java in the onCreateOptionsMenu()
  • Change the colorPrimary and colorPrimaryDark to #00897B and #00796B respectively

メニューレイアウトを拡張するために、MainActivity.javaに以下のメソッドを追加してください。

@Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_main, menu);

        return super.onCreateOptionsMenu(menu);
    }

メニューのメイン.xmlは次のようになっています。

<menu xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    tools:context="com.scdev.tablayoutviewpager.MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_search"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        android:icon="@drawable/search"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_add"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        android:icon="@drawable/add"
        app:showAsAction="ifRoom" />
</menu>

上記の変更を行うと、このようなものができあがります。このチュートリアルはこれで終了です。Android TabLayoutViewPagerプロジェクトは以下のリンクからダウンロードできます。

Android TabLayout ViewPager プロジェクトをダウンロードする。

コメントを残す 0

Your email address will not be published. Required fields are marked *


广告
広告は10秒後に閉じます。
bannerAds