ナビゲーションドロワーのカスタマイズ2


Pocket

ナビゲーションドロワーのカスタマイズを再度やってみました。
今回はよりこれに近づけるようタイトル、アイコン、カウンターをつけてみました。

こんな感じ。

drawerlayout_custom
 

やり方

基本的にはGoogle DevelopersのサンプルコードをベースにListViewのレイアウトをいじっています。

Creating a Navigation Drawer
 

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
 
 

動かしてみると微妙にもっさりした動作になっているのが気になりますが・・・
 
 

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>