ListView에 adapter를 이용해서 custom View를 만들었는데, 체크 박스 관련 문제가 있어서 질문 드립니다.

소스 내용 가운데 핵심적인 부분은 다음과 같습니다.

public class SpamBlockSpamwords extends Activity
{
 private ListView m_lvSpamWordList = null;
 private CheckBox m_cbListCheck = null;
 
 private ArrayList<Item> m_alTextArrayList = null;
 private MyArrayAdapter m_adapter = null;
 
 private SQLiteDatabase m_sqlDatabase = null;
 private Cursor m_cCursor = null;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
      
        setContentView(R.layout.spam_block_spamwords);
          
        m_lvSpamWordList = (ListView)this.findViewById(R.id.ListView);
    
        m_alTextArrayList = new ArrayList<Item>();
        m_adapter = new MyArrayAdapter(this, R.layout.spam_list_item, m_alTextArrayList);
       
        m_lvSpamWordList.setAdapter(m_adapter);

        m_sqlDatabase = openOrCreateDatabase("spamwords.db", SQLiteDatabase.CREATE_IF_NECESSARY, null);
               
        if (!m_sqlDatabase.isOpen())
         finish();

        String strSQL =
      "CREATE TABLE IF NOT EXISTS spamwords " +
      "(" +
      "value TEXT" +
      ");";
    
     m_sqlDatabase.execSQL(strSQL);
       
        m_cCursor = m_sqlDatabase.rawQuery("SELECT value FROM spamwords", null);
        int nSpamwordNum = m_cCursor.getCount();
               
        if (nSpamwordNum > 0)
        {
            for (int nIndex = 0; nIndex < nSpamwordNum; ++nIndex)
            {
             m_cCursor.moveToNext();
             
             String strSpamWord = m_cCursor.getString(0);
             Item i = new Item(strSpamWord);
             
             m_alTextArrayList.add(i);
            }
        }
    }

 private class MyArrayAdapter extends ArrayAdapter<Item>
 {
        private ArrayList<Item> items;
 
        public MyArrayAdapter(Context context, int textViewResourceId, ArrayList items)
        {
                super(context, textViewResourceId, items);
                this.items = items;
        }
       
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            View v = convertView;
           
            if (null == v)
            {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.spam_list_item, null);
            }
           
            Item i = (Item)items.get(position);
           
            if (null != i)
            {
                TextView tv = (TextView) v.findViewById(R.id.toptext);
                
                m_cbListCheck = (CheckBox)v.findViewById(R.id.ListCheckbox);
                
                if (null != tv)
                 tv.setText(i.getListText());

               if (m_cbListCheck.isChecked())
                {
                }
            }
          
            return v;
        }
 } 

소스 내용을 간략히 요약하면, DB로부터 데이터를 가지고 와서 ListView에 채우는데, 이 때 ListView는 adapter에 의해 각 List가 TextView와 CheckBox로 이루어지게 됩니다.  실행을 하면 다음과 같은 화면이 됩니다. 체크박스를 가지고 있는 List!!
실행화면.JPG 

ListView의 xml입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingLeft="10px"
    android:paddingRight="10px"   
    android:background='#ffffff'
    >
    <ListView 
     android:id="@+id/ListView"
     android:layout_width="fill_parent"
     android:layout_height="18dip"
     android:layout_weight="1"
     android:padding="0dip"
     android:drawSelectorOnTop="false"
     android:background='#ffffff'/>
</LinearLayout>  

Adapter로 ListView에 붙게(?) 되는 Layout입니다.
 <RelativeLayout xmlns:android="
http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:background='#ffffff'
     android:textColor='#000000'>

    <TextView
         android:id="@+id/toptext"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:gravity="center_vertical"
         android:padding="0px"
         android:textSize="30dip"
         android:textColor='#000000'
         android:layout_alignParentLeft="true"/>

 

  <CheckBox
         android:id="@+id/ListCheckbox"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:visibility="invisible" 
         android:layout_alignParentRight="true"/>

 </RelativeLayout>


문제가 되는 것은 앞서 소스부분에 붉은색으로 표시한 부분인데요,
getView() 내부에서 CheckBox의 check상태 여부를 isChecked()함수로 체크를 해보면 이때 getView()의 param으로
넘어오는 position 값이 이상합니다.

예를 들어 위에 첨부한 실행화면과 같이 list에 5개의 data가 존재하는 경우,
position 값은 맨 위에서부터 0~4까지의 값을 가지게 되는데,
position 값이 1인 두 번째 list의 CheckBox를 check하고 debuging 모드에서 각 position 별로
m_cbListCheck.isChecked()의 값을 확인해보면 position이 1일 때 m_cbListCheck.isChecked()의 값이 true가 넘어오는게 아니라
position이 3일 때 true가 넘어옵니다.

여러 경우를 테스트해 본 결과, 이상하게 CheckBox의 indexing이 아래로 부터 이루어져, 위에서 부터 n번째 list에 있는 CheckBox를
선택하면 m_cbListCheck.isChecked()는 list의 아래에서부터 n번째에 해당하는 position 값인 경우에 true가 반환되는 것입니다.

이 문제 때문에 진짜 몇일 동안 별짓을 다 해보았지만, 왜 그런 것인지 알 수가 없네요.
ListView에 TextView+CheckBox 형태를 붙이는게 잘못된게 아닐까 해서 ListView에 붙이는 Layout을
TextView+CheckBox가 아닌, CheckedTextView로도 대체해보았는데,
이 경우에도 역시 check된 상태 값이 position이 list의 역순으로 해서 넘어오는 것 같네요.

무엇인지 잘못된 것인지 고수님들의 지도 부탁 드립니다.

그리고 추가적으로 한 가지더 궁금한 것이,
위와 같이 ListView에 TextView와 CheckBox를 붙일 경우,
TextView의 Text의 경우 Adapter에 넣는 ArrayList에 의해 몇 번 째의 값을 바꿀 수가 있는데,
CheckBox의 경우 이게 몇번째 list의 CheckBox인지를 도무지 알 수가 없더군요.
유일한 방법이 getView()에 position을 보고 아는 방법 뿐인듯 한데 position이 반대로 넘어오니......;;;;

이때 CheckBox를 TextView와 같이 getView()가 아닌 다른 곳에서 몇 번째 CheckBox를 강제로 false, true
시킬 수 있는 방법이 있을까요?
 
이 추가 질문은 그냥 사용을 하다가 불편해서 드리는 질문이고,
위에 check된 CheckBox의 position이 반대로 넘어오는 문제가 지금 정말 시급합니다.
많은 도움 부탁 드립니다...... T_T