ボタン付きの ListView

Android 右端にボタンを配置した ListView を作るパターンはある程度、汎用的に書けるのではと
思い立ち、以下のように書いてみた。
まずは、レイアウトの XML、ほとんどのケースで以下のようになるであろう。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:background="@android:drawable/screen_background_light" >
    <TextView
        android:id="@+id/titleTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"
        android:text="Medium Text"
        android:textColor="#000000"
        android:background="@android:drawable/screen_background_light"
        android:textAppearance="?android:attr/textAppearanceMedium" />
    <ImageButton

        android:id="@+id/deleteImageButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:background="@android:drawable/screen_background_light"
        android:src="@android:drawable/ic_menu_delete" />
</LinearLayout>

そして、汎用的な抽象クラスとして、ArrayAdapter を以下のように、、、

import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
/**
 * RightButtonListAdapter
 */

public abstract class RightButtonListAdapter extends ArrayAdapter<Map<String,Object>>{
   private LayoutInflater layoutInflater;
   private TextView titleTextView;
   private int rowId;
   private int textViewId;
   private int imageButtonId;

   private String titleKey;

   public abstract void onRowClick(int position,Map<String,Object> item);
   public abstract void onImageButtonClick(int position,Map<String,Object> item);

   /**
    * コンストラクタ
    * @param context Context
    * @param rowId 1行分の layout の id
    * @param textViewId タイトル表示 TextView の id
    * @param imageButtonId 右端の ImageButton の id
    * @param titleKey 引数itemslist の Mapから表示タイトルを参照するキー
    * @param itemslist List<Map<String,Object>> Mapは、titleKeyが指すタイトルをvalueとして持つことが必須
    */

   public RightButtonListAdapter(Context context,int rowId,int textViewId,int imageButtonId
,String titleKey,List<Map<String,Object>> itemslist){
      super(context,0,itemslist);
      this.rowId = rowId;
      this.textViewId = textViewId;
      this.imageButtonId = imageButtonId;

      this.titleKey = titleKey;
      layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   }
   @Override
   public View getView(final int position,View convertView,ViewGroup parent){
      View view = convertView==null ? layoutInflater.inflate(rowId,null) : convertView;
      final Map<String,Object> item = this.getItem(position);
      if (item != null){
         titleTextView = (TextView)view.findViewById(textViewId);
         titleTextView.setText(item.get(titleKey).toString());
         *1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
               onImageButtonClick(position,item);
            }
         });
         view.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
               onRowClick(position,item);
            }
         });
      }
      return view;
   }
}

これを使うサンプルは、、、

定数を以下のように用意、、、

static String TITLE_KEY = "TITLE_KEY";
static String DETAIL_KEY = "DETAIL_KEY";

表示対象のリストをメソッドとともに、以下のように、、、

final List<Map<String,Object>> tlist = new ArrayList<Map<String,Object>>();
tlist.add(createItemMap("テスト1","test 1"));
tlist.add(createItemMap("テスト2","test 2"));
tlist.add(createItemMap("テスト3","test 3"));

private Map<String,Object> createItemMap(String title,String detail){
   Map<String,Object> map = new HashMap<String,Object>();
   map.put(TITLE_KEY,title);
   map.put(DETAIL_KEY,detail);
   return map;
}

ListView に以下のようにセット

ListView listview = (ListView)findViewById(R.id.listView);
listview.setAdapter(new RightButtonListAdapter(this , R.layout.multibuttonlist_row
                                                ,R.id.titleTextView
                                                ,R.id.deleteImageButton

                                                ,TITLE_KEY
                                                ,tlist){
   @Override
   public void onRowClick(int position,Map<String,Object> item){

      String message = "Title Click  position=" + position + " title="+item.get(TITLE_KEY);
      Toast.makeText(IconLinkListSampleActivity.this,message,Toast.LENGTH_SHORT).show();
   }
   @Override
   public void onImageButtonClick(int position,Map<String,Object> item){

      String message = "Button Click  position=" + position + " datail="+item.get(DETAIL_KEY);
      Toast.makeText(IconLinkListSampleActivity.this,message,Toast.LENGTH_SHORT).show();
   }
}
);

*1:ImageButton)view.findViewById(imageButtonId