现在的位置: 首页 > 综合 > 正文

Android AlertController的小bug?

2013年02月13日 ⁄ 综合 ⁄ 共 2467字 ⁄ 字号 评论关闭

上周五在帮一个实习生调试程序的时候发现了这个问题,他当时想实现一个这样的功能:当用户选择删除时,以dialog的方式弹出数据列表,并且每个数据都有一个checkbox,用户选择后可以进行删除过滤。具体的接口是:

 

[java] view
plain
copy

  1. public AlertDialog.Builder setMultiChoiceItems (Cursor cursor, String   
  2.                    isCheckedColumn, String labelColumn,           
  3.                    DialogInterface.OnMultiChoiceClickListener listener)   

 

其中参数cursor是从数据库中查找返回的结果,isCheckedColumn对应数据库中一列的名称,该项为整型值,0代表为选中,1代表选中,labelColumn代表UI显示的字段,listener为注册的点击监听器。然后需要实现下面的函数接口:

[java] view
plain
copy

  1. public abstract void onClick (DialogInterface dialog, int which, boolean   
  2.                                 isChecked)   

其中参数dialog为你创建的对话框,which表示你点击的表项在list中的位置,isChecked表示该项是否被选中。

 

当时查询的结果也能显示出来,但是点击的checkbox没有变化,加了log之后发现isChecked已经为true了,也就是说应该显示被选中的状态。仔细看了下文档,发现没有使用不对的地方,最后只能查看framework中的实现代码了,初开始以为是点击的事件触发了,只是UI没有更新而已。

 

但是listview中实现的代码如下(frameworks/base/core/java/android/widget/CursorAdapter.java):

[java] view
plain
copy

  1. adapter = new CursorAdapter(mContext, mCursor, false) {  
  2.   private final int mLabelIndex;  
  3.   private final int mIsCheckedIndex;  
  4.   {  
  5.     final Cursor cursor = getCursor();  
  6.     mLabelIndex = cursor.getColumnIndexOrThrow(mLabelColumn);  
  7.     mIsCheckedIndex = cursor.getColumnIndexOrThrow(mIsCheckedColumn);  
  8.    }  
  9.   
  10.     @Override  
  11.     public void bindView(View view, Context context,   
  12.             Cursor cursor) {  
  13.       CheckedTextView text = (CheckedTextView) view.findViewById  
  14.                   (R.id.text1);  
  15.       text.setText(cursor.getString(mLabelIndex));  
  16.       listView.setItemChecked(cursor.getPosition(),  
  17.                    cursor.getInt(mIsCheckedIndex) == 1);  
  18.     }  
  19.       
  20.     @Override  
  21.     public View newView(Context context, Cursor cursor,   
  22.             ViewGroup parent) {  
  23.       return mInflater.inflate(R.layout.select_dialog_multichoice,  
  24.                   parent, false);  
  25.     }  
  26.                           
  27. };  



 

这个函数会在任何事件触发的时候都会调用的重新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的程序员也是人,是人都会犯点小错误的,希望对有可能使用这个控件的人有所帮助:)

抱歉!评论已关闭.