ナビゲーションドロワーのカスタマイズを再度やってみました。
今回はよりこれに近づけるようタイトル、アイコン、カウンターをつけてみました。
こんな感じ。
やり方
基本的にはGoogle DevelopersのサンプルコードをベースにListViewのレイアウトをいじっています。
1.ListViewのレイアウトファイルを作成
ListViewで表示する1行文のレイアウトを作成
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_item" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="48dp" > <!-- Icon --> <ImageView android:id="@+id/item_icon" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginLeft="12dp" android:layout_marginRight="12dp" android:src="@drawable/ic_launcher" /> <!-- Item Text --> <TextView android:id="@+id/item_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_toRightOf="@+id/item_icon" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeightSmall" android:text="item" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="#FFFFFF" /> <!-- Counter --> <TextView android:id="@+id/item_counter" android:layout_width="32dp" android:layout_height="32dp" android:layout_marginRight="16dp" android:layout_marginTop="8dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:background="@drawable/bg_counter" android:gravity="center" android:textColor="#FFFFFF" android:textSize="12sp" android:textStyle="bold" android:textAppearance="?android:attr/textAppearanceSmall" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginBottom="1dp" android:layout_marginTop="1dp" android:background="#999999"/> </LinearLayout>
2.ListViewに表示するデータのクラスを定義
「アイコンのリソースID」「テキスト」「カウンタ」をメンバ変数に持つDrawerItemクラスを作成。
サンプルなのでメンバ変数は全てPublicにしてしまう。
public class DrawerItem { public int mIconRes; public String mTitle; public int mCounter; public DrawerItem(int icon, String title) { mIconRes = icon; mTitle = title; mCounter = 0; } public void countUp() { mCounter++; } }
3.CustomAdapterクラスの作成
ArrayAdapterクラスを継承して1.で作ったレイアウトに変換するadapterを作成する。
今回はprivateクラスにしてMainActivity.javaに書いてます。
private class CustomArrayAdapter extends ArrayAdapter<DrawerItem> { public CustomArrayAdapter(Context context, DrawerItem[] objects) { super(context, 0, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { Log.d("MainActivity", "getView:" + position); View view = convertView; // Viewが準備されていなければ新しく生成 if (view == null) { view = LayoutInflater.from(getContext()).inflate(R.layout.drawer_list_item, null); } DrawerItem data = super.getItem(position); ImageView icon = (ImageView)view.findViewById(R.id.item_icon); icon.setImageResource(data.mIconRes); TextView title = (TextView)view.findViewById(R.id.item_title); title.setText(data.mTitle); TextView counter = (TextView)view.findViewById(R.id.item_counter); if (data.mCounter > 0) { counter.setText(String.valueOf(data.mCounter)); counter.setVisibility(View.VISIBLE); } else { counter.setVisibility(View.INVISIBLE); } return view; }
これでListViewにアイコン、アイテムテキスト、カウンタが追加されました。
4.ListViewにタイトルを追加
ListViewのタイトル(ヘッダ)はaddHeaderViewで追加できます。
まずは、タイトル用のレイアウトを作成。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_header" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="32dp" > <TextView android:id="@+id/item_header" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="16dp" android:layout_alignParentBottom="true" android:gravity="center_vertical" android:text="Planets" android:textStyle="bold" android:textColor="#FFFFFF" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginBottom="1dp" android:layout_marginTop="1dp" android:background="#999999"/> </LinearLayout>
これをListViewにaddheaderViewしてやります。
mDrawerList.addHeaderView(LayoutInflater.from(this).inflate(R.layout.drawer_list_header, null));
ざっくり説明ですが以上です。
後は、アイテムクリックされた時にカウントアップする処理を書けばそれっぽく動くとおもいますが、カウンタ数はonSaveInstanceStateなどで保存していないため、画面回転などActivityが破棄されるとクリアされます。
ソースコードはGitHubに上げてあります。
https://github.com/workpiles/CustomDrawer2
動かしてみると微妙にもっさりした動作になっているのが気になりますが・・・