Checkable 実装カスタマイズの方法

ListView CheckedTextView 以外の方法で選択行を自由に表現したいケースは
たくさんある。
android.widget.Checkable 実装のカスタマイズビューで、タップ時だけでなく、選択状態の場合に、、
背景を指定したい。

但し、ここで書くサンプル・パターンはポイントを押さえる為で単純なデザインのみであり、
実践は複雑なデザインが目的である。
単純なデザインなら、他の方法を使うべきである。



res/vaules/attrs.xml を用意する。


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CheckableLinearLayout">
       <attr name="selectedBackgroundColor" format="color" />
       <attr name="defaultBackgroundColor"  format="color" />
    </declare-styleable>
</resources>

LinearLayout を継承して、android.widget.Checkable をインターフエースとして実装する
選択用の行レイアウトを作る → yip.yip.CheckableLinearLayout


package yip.yip;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.Checkable;
import android.widget.LinearLayout;
/**
 * CheckableLinearLayout
 */

public class CheckableLinearLayout extends LinearLayout implements Checkable{
   private boolean mChecked;
   private int mSelectedBackgroundColor;
   private int mDefaultBackgroundColor;


   public CheckableLinearLayout(Context context, AttributeSet attrs) {
      super(context, attrs, 0);
      TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CheckableLinearLayout, 0, 0);
      mSelectedBackgroundColor = array.getColor(R.styleable.CheckableLinearLayout_selectedBackgroundColor, 0xff33b5e5 );
      mDefaultBackgroundColor = array.getColor(R.styleable.CheckableLinearLayout_defaultBackgroundColor,   0xff222222 );
      array.recycle();
   }
   @Override
   public boolean isChecked(){
      return mChecked;
   }
   @Override
   public void setChecked(boolean checked){
      mChecked = checked;
      setBackgroundColor(checked ? mSelectedBackgroundColor : mDefaultBackgroundColor);
      refreshDrawableState();

   }
   @Override
   public void toggle(){
      mChecked = !mChecked;
   }
}

使用例

res/layout/sample_row.xml


<yip.yip.CheckableLinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/yip.yip.app.sample"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:selectedBackgroundColor="#c73650"
    app:defaultBackgroundColor="#444444"

    android:orientation="horizontal" >
    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_margin="16dp"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</yip.yip.CheckableLinearLayout>

 ArrayAdapterの getView だけオーバーライドする

final TextView textView = (TextView)findViewById(R.id.textView1);
final ListView listview = (ListView)findViewById(R.id.listView1);
listview.setAdapter(new ArrayAdapter<Item>(this, 0, mlist){
   LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   @Override
   public View getView(int position,View convertView,ViewGroup parent){

      View view = convertView==null ? inflater.inflate(R.layout.sample_row, null) : convertView;
      TextView tv = (TextView)view.findViewById(R.id.text1);
      Item item = mlist.get(position);
      tv.setText(item.name);
      return view;
   }
}
);
listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener(){
   @Override
   public void onItemClick(AdapterView<?> parent, View view, int position, long id){

      // 選択後の処理など。。。
      BaseAdapter adapter = (BaseAdapter)parent.getAdapter();
      Item item = (Item)adapter.getItem(position);
      textView.setText(item.name);
      mSelectedPosition = position;
   }
}
);

画面のレイアウト

<?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="vertical" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:padding="10dp"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#000000" />
    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" >
    </ListView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/statusButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="status" />
        <Button
            android:id="@+id/backButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="BACK" />
    </LinearLayout>
</LinearLayout>

画面は、、、

f:id:posturan:20160313195136p:plain



デフォルトの色では、、

f:id:posturan:20160313195130p:plain