上週五在幫一個實習生調試程序的時候發現了這個問題,他當時想實現一個這樣的功能:當用戶選擇刪除時,以dialog的方式彈出數據列表,並且每個數據都有一個checkbox,用戶選擇後可以進行刪除過濾。具體的接口是:
其中參數cursor是從數據庫中查找返回的結果,isCheckedColumn對應數據庫中一列的名稱,該項爲整型值,0代表爲選中,1代表選中,labelColumn代表UI顯示的字段,listener爲註冊的點擊監聽器。然後需要實現下面的函數接口:
其中參數dialog爲你創建的對話框,which表示你點擊的表項在list中的位置,isChecked表示該項是否被選中。
當時查詢的結果也能顯示出來,但是點擊的checkbox沒有變化,加了log之後發現isChecked已經爲true了,也就是說應該顯示被選中的狀態。仔細看了下文檔,發現沒有使用不對的地方,最後只能查看framework中的實現代碼了,初開始以爲是點擊的事件觸發了,只是UI沒有更新而已。
但是listview中實現的代碼如下(frameworks/base/core/java/android/widget/CursorAdapter.java):
這個函數會在任何事件觸發的時候都會調用的重新bind的動作,其中listView.setItemChecked(cursor.getPosition(), cursor.getInt(mIsCheckedIndex) == 1);是用來設置checkbox狀態的,原來每次都根據數據庫mIsCheckedIndex該列的值來決定是否選中的,所以我首先想到的是我應該在上面onClick被調用的時候去更新數據庫。
可是結果並沒有我想象的那樣發生,UI仍然沒有更新。但是我查數據庫發現裏面的值已經進行了修改,會不會沒有重新調用查詢?於是我看到CursorAdapter的第三個參數,或許看到它的使用註釋你就明白了:
public CursorAdapter (Context context, Cursor c, boolean autoRequery)
Constructor
Parameters
context | The context |
---|---|
c | The cursor from which to get the data. |
autoRequery | If true the adapter will call requery() on the cursor whenever it changes so the most recent data is always displayed. |
於是乎我們把第三個參數改爲true就ok了。開發Android的程序員也是人,是人都會犯點小錯誤的,希望對有可能使用這個控件的人有所幫助:)