为 ListFragment
扩展 SimpleCursorAdapter
的自定义适配器无法正确显示数据库中的项目。它不在 TextView 中显示文本,我还需要对光标做些什么才能显示正确的文本?
我以为我必须覆盖 bindView
但那没有效果
设置适配器:
public void populateList(){
String[] fields = new String[] {BowlersDB.NAME};
Cursor c = getActivity().getContentResolver().query(BowlersDB.CONTENT_URI,
new String[] {BowlersDB.ID,BowlersDB.NAME},null,null,BowlersDB.NAME + " COLLATE LOCALIZED ASC");
mAdapter = new CheckAdapter(getActivity(),R.layout.check_listview,c,fields,new int[] {R.id.nameCheckTV});
setListAdapter(mAdapter);
getLoaderManager().initLoader(0,null,this);
}
适配器:
public class CheckAdapter extends SimpleCursorAdapter{
Context context;
Cursor c;
public CheckAdapter(Context context, int layout, Cursor c,String[] from, int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.c = c;
// TODO Auto-generated constructor stub
}
@Override
public void bindView(View view,Context context,Cursor cursor){
String st = cursor.getString(cursor.getColumnIndex(BowlersDB.NAME));
TextView tv = (TextView)view.findViewById(R.id.nameCheckTV);
tv.setText(st);
}
@Override
public View getView(final int position,View convertView,ViewGroup parent){
if(convertView == null){
LayoutInflater inflator = getLayoutInflater();
convertView = inflator.inflate(R.layout.check_listview,null);
}
CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkBox1);
cb.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
CheckBox check = (CheckBox)v.findViewById(R.id.checkBox1);
int pos = position;
if(check.isChecked()){
mCheckedItems.add(position);
}else if(!check.isChecked()){
for(int i=0;i< mCheckedItems.size();i++){
if(mCheckedItems.get(i) == position){
mCheckedItems.remove(i);
}
}
}
}
});
return convertView;
}
}
最佳答案
我想我明白了。查看 CursorAdapter.getView()
的实现.请注意 bindView()
和 newView()
是如何在 getView()
中调用的。看起来通过覆盖 getView()
您可以确保您的 CursorAdapter
永远不会调用 bindView()
。要么只将所有内容放在 getView()
中,要么只放在 newView()
和 bindView()
中,但不能同时放在两者中。
编辑一:
四件事:
我已经阅读了有关
CursorAdapter
的内容,看起来您想覆盖bindView()
而不是getView()
。看起来getView()
为要显示的每一行调用了两次,这在某种程度上阻止了光标更新,因此始终指向第一行。我认为这就是为什么您的ListView
只显示第一行的原因。此外,ListView 的默认CursorAdapter
实现将为您回收 View ,因此实际上不需要覆盖getView()
(查看此 answer 了解更多信息) .在创建
mAdapter
时,您应该将一个空的Cursor
传递给构造函数。Cursor
将在onLoadFinished
中传递(当Loader
完成查询时),并使用swapCursor(光标)
。您的
onCreateLoader()
方法将创建(或启动)将执行初始查询的Loader
。确保它看起来像这样,@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String[] projection = { BowlersDB.ID, BowlersDB.NAME }; CursorLoader cursorLoader = new CursorLoader(getActivity(), BowlersDB.CONTENT_URI, projection, null, null, null); return cursorLoader; }
确保您使用了正确的
SimpleCursorAdapter
构造函数……您当前使用的构造函数已被弃用! (将0
作为标志传递...CursorLoader
将为您注册一个内容观察器,因此您无需传递任何特殊内容)。
编辑二:
澄清一下,bindView()
方法是用Cursor
当前位置的数据填充行的小部件的地方。将 Cursor
预先放置在正确的行上。您需要从 Cursor
中提取数据并将其倒入您想要的小部件中。换句话说,您需要查询行的 ID(而不是使用 getView()
中的“position”参数)。尝试在 bindView()
中设置 onClickListener
,如下所示:
final int rowId = cursor.getInt(cursor.getColumnIndex("_id"));
CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkBox1);
cb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int position = rowId;
/* you now know this row's position. do what you need to do. */
}
});
关于android - 光标未使用自定义适配器正确绑定(bind)文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8902141/