【Android】CheckedTextView - 用於 ListView 的 CheckBox

當想要在 ListView 呈現具 CheckBox 的選項列表時,卻得不到預期的效果 -- 在 打勾方框 點選 和 在列表空白處點選所引發的是不同的 event,而點在 CheckBox 上的,好像也無法得知是在 ListView 內的哪個 item......踹了好久,才發現有 CheckedTextView 這個元件。

先建立主 Activitylayout(檔名: activity_main.xml):
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" >
    </ListView>

</LinearLayout>


然後建立 ListViewitemlayout(檔名: list_item.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="wrap_content"
 android:orientation="horizontal" >

    <CheckedTextView
      android:id="@+id/check1"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:gravity="center_vertical"
      android:checkMark="?android:attr/listChoiceIndicatorMultiple"
      android:checked="true"
      android:text="CheckedTextView"
      android:textAppearance="?android:attr/textAppearanceMedium" />
    
</LinearLayout>

上面那個 checkMark,會讓打勾方框在最右邊,如下圖:

如果要讓打勾方框在文字左邊,則將
android:checkMark="?android:attr/listChoiceIndicatorMultiple" 改成:
android:drawableLeft="?android:attr/listChoiceIndicatorMultiple"
android:drawableRight="?android:attr/listChoiceIndicatorMultiple" 效果則等同 android:checkMark="?android:attr/listChoiceIndicatorMultiple"
另外還有 drawableTopdrawableBottom 可指定



建立主程式(檔名: MainActivity.java) :
package com.example.chktextv;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;

public class MainActivity extends Activity
{
    private static final String TAG = "MainActivity";
    List<String> list;
    ListView listview;
    List<Boolean> listShow;    // 這個用來記錄哪幾個 item 是被打勾的
 
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        listview = (ListView) findViewById(R.id.ListView1);
        listview.setOnItemClickListener(new OnItemClickListener()
                                       {
                                            public void onItemClick(AdapterView<?> parent, View v, int position, long id)
                                            {
                                                 CheckedTextView chkItem = (CheckedTextView) v.findViewById(R.id.check1);
                                                 chkItem.setChecked(!chkItem.isChecked());
                                                 Toast.makeText(MainActivity.this, "您點選了第 "+(position+1)+" 項", Toast.LENGTH_SHORT).show();
                                                 listShow.set(position, chkItem.isChecked());
                                            }
                                       }
                                      );

        listShow = new ArrayList<Boolean>();
        list = new ArrayList<String>();
        for(int x=1;x<11;x++)
        {
             list.add("項目"+x);
             listShow.add(true);
        }
        ListAdapter adapterItem = new ListAdapter(this, list);
        listview.setAdapter(adapterItem);
    }

    ...
    ...

    // 要離開前檢查哪些 item 是打勾的
    @Override
    public void onBackPressed()
    {
        for(int x=0;x<listShow.size();x++)
        {
            Log.d(TAG,"listShow("+x+") is "+listShow.get(x));
            if(listShow.get(x)==true)
            {
                // 寫下您對打勾 item 的對應處理
                ...
                ...
            }
        }
        finish();
    }
}

建立 ListAdapter.java
package com.example.chktextv;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckedTextView;

public class ListAdapter extends BaseAdapter
{
    private Activity activity;
    private List<String> mList;
    
    private static LayoutInflater inflater = null;
    
    public ListAdapter(Activity a, List<String> list)
    {
        activity = a;
        mList = list;
        inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount()
    {
        return mList.size();
    }

    public Object getItem(int position)
    {
        return position;
    }

    public long getItemId(int position)
    {
        return position;
    }
    
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View vi = convertView;
        if(convertView==null)
        {
            vi = inflater.inflate(R.layout.list_item, null);
        }
        
        CheckedTextView chkBshow = (CheckedTextView) vi.findViewById(R.id.check1);
        
        chkBshow.setText(mList.get(position).toString());
        
        return vi;
    }
}