2013/02/07

SimpleCursorAdapterを使っているListViewのアイテム要素にListenerをつける

AndroidでSimpleCursorAdapterを使っているListViewでレイアウトの中にListenerをつけたので、その備忘録として。

やりたかったのは、SimpleCursorAdapterを使っているListViewのItem要素の中に複数のclickできるViewがあり、それぞれのclickで異なる動作をすること。

ポイントは

  • ListViewの拡張
  • SimpleCursorAdapterの拡張

サンプルとして使うItem要素のxmlはこんな感じ
(今回はTextViewにlistenerをつける。
@stringと@dimensは別に定義してるもの)

list_item.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="wrap_content"
    android:paddingTop="8dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingBottom="8dp"
    android:orientation="vertical" >
    
    <TextView
        android:id="@+id/name_textview"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="@dimen/text_size_large" />
    
    <TextView
        android:id="@+id/point_textview"
        android:layout_below="@id/name_textview"
        android:layout_alignParentLeft="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="@dimen/text_size_small" />
    
    <TextView
        android:id="@+id/delete_textview"
        android:layout_below="@id/name_textview"
        android:layout_alignParentRight="true"
        android:layout_width="48dp"
        android:layout_height="24dp"
        android:gravity="center"
        android:text="@string/textview_label_delete"
        android:textSize="@dimen/text_size_small" />
    
    <View
        android:id="@+id/separator_view_to_left_of_delete"
        android:layout_below="@id/name_textview"
        android:layout_toLeftOf="@id/delete_textview"
        android:layout_width="2dp"
        android:layout_height="24dp"
        android:background="@android:color/darker_gray" />
    
    <TextView
        android:id="@+id/edit_textview"
        android:layout_below="@id/name_textview"
        android:layout_toLeftOf="@id/separator_view_to_left_of_delete"
        android:layout_width="48dp"
        android:layout_height="24dp"
        android:gravity="center"
        android:text="@string/textview_label_edit"
        android:textSize="@dimen/text_size_small" />
    
    <View
        android:id="@+id/separator_view_to_left_of_edit"
        android:layout_below="@id/name_textview"
        android:layout_toLeftOf="@id/edit_textview"
        android:layout_width="2dp"
        android:layout_height="24dp"
        android:background="@android:color/darker_gray" />
    
    <TextView
        android:id="@+id/record_textview"
        android:layout_below="@id/name_textview"
        android:layout_toLeftOf="@id/separator_view_to_left_of_edit"
        android:layout_width="48dp"
        android:layout_height="24dp"
        android:gravity="center"
        android:text="@string/textview_label_record"
        android:textSize="@dimen/text_size_small" />
    
</RelativeLayout>

次にListViewを拡張したMyListView。
/**
 * リスト内にボタンを配置して、ボタンが押された時にonItemClickを通知するListView
 */
public class MyListView extends ListView implements OnClickListener {
    
    /**
     * コンストラクタ
     */
    public MyListView(Context context) {
        super(context);
    }
    
    /**
     * コンストラクタ
     */
    public MyListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onClick(View v) {
        int pos = (Integer)v.getTag();
        this.performItemClick(v, pos, v.getId());
    }
}

次にSimpleCursorAdapterを拡張したMyCursorAdapter
private class MyCursorAdapter extends SimpleCursorAdapter {

        public MyCursorAdapter(Context context, int layout, Cursor c,
                String[] from, int[] to, int flags) {
            super(context, layout, c, from, to, flags);
        }
        
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // viewのセットなどはスーパークラスのメソッドに任せる
            View view = super.getView(position, convertView, parent);
            
            /*
             * それぞれのTextViewにpositionTagと
             * MyListViewのlistenerをつける
             */
            TextView deleteTextView = (TextView)view.findViewById(
                    R.id.delete_textview);
            deleteTextView.setTag(position);
            deleteTextView.setOnClickListener((MyListView)parent);
            
            TextView editTextView = (TextView)view.findViewById(
                    R.id.edit_textview);
            editTextView.setTag(position);
            editTextView.setOnClickListener((MyListView)parent);

            TextView recordTextView = (TextView)view.findViewById(
                    R.id.record_textview);
            recordTextView.setTag(position);
            recordTextView.setOnClickListener((MyListView)parent);
            return view;
        }
    }

これで、アイテム要素の中のonClick()でListViewのonItemClick()が呼ばれるようになるので、
onItemClick()の中でidで処理を切り替えればOK。
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {

            switch(view.getId()) {
                case R.id.delete_textview:
                    // 消去の時の処理
                    break;
                case R.id.edit_textview:
                    // 編集の時の処理
                    break;
                case R.id.record_textview:
                    // 記録の時の処理
                    break;
                default:
                    // 通常のonItemClick()の時の処理
                    break;
            }
        }

参考にした記事
ListViewの中のボタンのクリックイベントをActivityに通知する

0 件のコメント:

コメントを投稿