ListView の選択色や文字色のメモ(2)

ListView の選択色や文字色のメモ(1) の続き、、

ポイントは、TextView に、ColorStateList を指定して、
更に View に、setOnTouchListener で、タッチして離れりたり、
なぞった時に文字列の色を戻す処理を入れる。

前回のメモ(1)と比べてかなり長いコードになる。

final List<Item> list = getList();

ListView listview = (ListView)findViewById(R.id.listView);
listview.setAdapter(new BaseAdapter(){
   LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   @Override
   public View getView(int position, View convertView, ViewGroup parent){
      View view = convertView==null ? layoutInflater.inflate(android.R.layout.simple_list_item_2, null) : convertView;
      final Item item = list.get(position);

      final TextView titleTextView = (TextView)view.findViewById(android.R.id.text1);
      titleTextView.setText(item.get(Item.TEXT1).toString());
      titleTextView.setTextColor(new ColorStateList(
         new int{
               new int{ android.R.attr.state_selected }
               ,new int
{ -android.R.attr.state_selected }
         },
         new int{
               Color.argb(0xff,0x0,0x0,0x0)
               ,Color.argb(0xff,0xff,0xff,0xff)
         }
      )
);
      final TextView descriptionTextView = (TextView)view.findViewById(android.R.id.text2);
      descriptionTextView.setText(item.get(Item.TEXT2).toString());
      descriptionTextView.setTextColor(new ColorStateList(
         new int
{
               new int
{ android.R.attr.state_selected }
               ,new int{ -android.R.attr.state_selected }
         },
         new int
{
               Color.argb(0xff,0x50,0x50,0x50)
               ,Color.argb(0xff,0xa0,0xa0,0xa0)
         }
      )
);

      view.setOnTouchListener(new View.OnTouchListener(){
         @Override
         public boolean onTouch(View v, MotionEvent event){
            int action = event.getAction();
            if (action==MotionEvent.ACTION_DOWN || action==MotionEvent.ACTION_MOVE){
               titleTextView.setSelected(true);
               descriptionTextView.setSelected(true);
            }else{
               titleTextView.setSelected(false);
               descriptionTextView.setSelected(false);
            }
            return false;
         }
      });


      view.setOnClickListener(new View.OnClickListener(){
         @Override
         public void onClick(View v){
            titleTextView.setSelected(false);
            descriptionTextView.setSelected(false);
            startActivity(new Intent(getApplicationContext(), item.getActivity())));
         }
      });
      view.setBackgroundResource(R.color.list_selector);
      return view;
   }
   @Override
   public long getItemId(int position){
      return position;
   }
   @Override
   public Object getItem(int position){
      return list.get(position);
   }
   @Override
   public int getCount(){
      return list.size();
   }
});

ColorStateList コンストラクタでインスタンスを作らずリソースで色を指定して、
XMLパースしてインスタンスを作る方法がある。


以下のようにリソースを用意する。

res/color/text_selector.xml
==================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_selected="true"
         android:state_pressed="false"
         android:color="#000000" />
   <item android:state_selected="false"
         android:state_pressed="false"
         android:color="#ffffff" />
</selector>
=================

setTextColor の実行を以下のように書き換える。

      final TextView titleTextView = (TextView)view.findViewById(android.R.id.text1);
      titleTextView.setText(item.get(Item.TEXT1).toString());
      try{
         titleTextView.setTextColor(ColorStateList.createFromXml(getResources(), getResources().getXml(R.color.text_selector)));
      }catch(Exception e){
         Logger.e(e.getMessage(),e);
      }
      final TextView descriptionTextView = (TextView)view.findViewById(android.R.id.text2);
      descriptionTextView.setText(item.get(Item.TEXT2).toString());
      try{
         descriptionTextView.setTextColor(ColorStateList.createFromXml(getResources(), getResources().getXml(R.color.text_selector)));
      }catch(Exception e){
         Logger.e(e.getMessage(),e);
      }

ただし、Exception を捕捉する記述は回避できない。