読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

ListViewの中にボタンを置くときの注意

Android

ListViewの各行にボタンを置いた時にハマりそうな箇所のメモです。

ListViewのsetOnItemClickListenerが動かない時

Adapterで使用しているレイアウトファイルを次のようにします。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal"
    android:padding="10dp" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="button" />

    <TextView
        android:id="@+id/text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1" />

</LinearLayout>

一番上のViewに android:descendantFocusability="blocksDescendants" を追加すればsetOnItemClickListenerでイベントが取得できるようになります。

行選択時にボタンの背景も変わってしまう場合

ちょっと分かりにくいかもしれませんが、下の状態は行を選択しているのですが何故かボタンも押されている状態になっています。

f:id:STAR_ZERO:20130419000026p:plain

4.0.3以下のバージョンで発生します。4.1.2では何もしなくても問題なかったです。

対応は以下のとおりです。

ボタンを拡張したクラスを作成
public class ListItemButton extends Button {

    public ListItemButton(Context context) {
        super(context);
    }

    public ListItemButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ListItemButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setPressed(boolean pressed) {
        if (pressed && getParent() instanceof View && ((View) getParent()).isPressed()) {
            return;
        }
        super.setPressed(pressed);
    }

}

setPressed をオーバーライドして、親Viewが押されている状態であれば即returnしてます。

拡張したボタンをViewに設定

先ほどのボタンをViewに設定します。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal"
    android:padding="10dp" >

    <com.example.listviewitem.ListItemButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="button" />

    <TextView
        android:id="@+id/text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1" />

</LinearLayout>

もっと簡単な対応がありそうな気もしますが、色々調べた結果こんな感じになりました。

参考

http://cyrilmottier.com/2011/11/23/listview-tips-tricks-4-add-several-clickable-areas/