光标不与自定义适配器正确文本装订 [英] Cursor not binding text correctly with custom adapter
问题描述
我的自定义适配器,扩展 SimpleCursorAdapter
我的 ListFragment
不能正确显示在我的数据库中的项目。它不会显示在TextView的文本,还有什么做我必须做的光标它显示正确的文本?
我想我不得不重写 bindView
但都没有效果。
设置适配器:
公共无效populateList(){ 的String []栏=新的String [] {} BowlersDB.NAME;
光标C = getActivity()。getContentResolver()查询(BowlersDB.CONTENT_URI,
新的String [] {BowlersDB.ID,BowlersDB.NAME},NULL,NULL,BowlersDB.NAME +分页中局部ASC);mAdapter =新CheckAdapter(getActivity(),R.layout.check_listview,C,领域,新的INT [] {R.id.nameCheckTV});
setListAdapter(mAdapter); getLoaderManager()initLoader(0,null,则此)。
}
适配器:
公共类CheckAdapter扩展SimpleCursorAdapter { 上下文语境;
光标C; 公共CheckAdapter(上下文的背景下,INT布局,光标C,的String []从,INT []到){
超(背景下,布局,C,从,到);
this.context =背景;
this.c = C;
// TODO自动生成构造函数存根
} @覆盖
公共无效bindView(查看视图,上下文的背景下,光标光标){
串ST = cursor.getString(cursor.getColumnIndex(BowlersDB.NAME)); TextView的电视=(TextView中)view.findViewById(R.id.nameCheckTV);
tv.setText(ST);
} @覆盖
公共查看getView(最终诠释的立场,观点convertView,父母的ViewGroup){
如果(convertView == NULL){
LayoutInflater充气= getLayoutInflater();
convertView = inflator.inflate(R.layout.check_listview,NULL);
} 复选框CB =(复选框)convertView.findViewById(R.id.checkBox1);
cb.setOnClickListener(新OnClickListener(){ @覆盖
公共无效的onClick(视图v){
复选框检查=(复选框)v.findViewById(R.id.checkBox1);
INT POS =位置;
如果(check.isChecked()){
mCheckedItems.add(位置);
}否则如果(!check.isChecked()){
的for(int i = 0; I< mCheckedItems.size();我++){
如果(mCheckedItems.get(ⅰ)==位置){
mCheckedItems.remove(ⅰ);
}
}
}
} });
返回convertView;
}}
我想我知道了。检查出的实施<一个href=\"http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/2.0_r1/android/widget/CursorAdapter.java#CursorAdapter.getView%28int%2Candroid.view.View%2Candroid.view.ViewGroup%29\"相对=nofollow> CursorAdapter.getView()
。请注意如何 bindView()
和 NewView的()
被称为在 getView()
。它看起来像通过重写 getView()
您可以确保您的的CursorAdapter
永远不会调用 bindView( )
。要么把一切都只是在 getView()
或仅在 NewView的()
和 bindView()
,但不能同时使用。
修改我:
四件事情:
-
我在
的CursorAdapter
读了S和它看起来像要覆盖bindView()
而不是getView()
。它看起来像getView()
为每个那是要显示的行调用两次,这是莫名其妙preventing光标被更新,因此总是指向第一行。我想这就是为什么你的的ListView
只显示第一行。此外,默认的的CursorAdapter
实施一个ListView将回收的意见你,所以覆盖getView()
还真是不必要的(看看这个 答案 获取更多信息)。 -
在创建
mAdapter
,你应该传递一个空光标
到构造。在光标
将在onLoadFinished
交付时(装载机
已完成查询),并会被绑定到适配器swapCursor(光标)
。 -
您
onCreateLoader()
方法将创建(或启动)的装载机
将执行初始查询。请确保它看起来像这样,@覆盖
公共装载机&LT;&光标GT; onCreateLoader(INT ID,捆绑参数){
的String [] =投影{BowlersDB.ID,BowlersDB.NAME}; CursorLoader cursorLoader =新CursorLoader(getActivity()
BowlersDB.CONTENT_URI,投影,NULL,NULL,NULL);
返回cursorLoader;
} -
请确保你使用正确的
SimpleCursorAdapter
构造......目前正在使用的一个是德precated! (通0
作为一个标志......在CursorLoader
将注册内容观察员你,让你不需要在什么特别的)来传递。
修改二:
要澄清一下,在 bindView()
的方法是,你从填充您行的与数据控件光标
目前的位置。你是递光标
pre-放置在适当的行。你需要获取数据了光标
,并倒入所需的部件。换句话说,你需要查询行的ID(而不是使用位置的说法getView()
)。尝试设置了 onClickListener
在 bindView()
的东西,如:
最终诠释ROWID = cursor.getInt(cursor.getColumnIndex(_ ID));复选框CB =(复选框)convertView.findViewById(R.id.checkBox1);
cb.setOnClickListener(新OnClickListener(){
@覆盖
公共无效的onClick(视图v){
INT位置= ROWID;
/ *你现在知道此行的地位。你需要做的事情。 * /
}
});
My Custom Adapter that extends SimpleCursorAdapter
for my ListFragment
does not display the items in my database correctly. it does not display the text in the TextView, what else do I have to do to the cursor for it to show the correct text?
I thought I had to override the bindView
but that had no effect
Setting the adapter:
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);
}
Adapter:
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;
}
}
I think I got it. Check out the implementation for CursorAdapter.getView()
. Notice how bindView()
and newView()
are called within getView()
. It looks like by overriding getView()
you are ensuring that your CursorAdapter
never calls bindView()
. Either put everything ONLY in getView()
or ONLY in newView()
and bindView()
, but not both.
EDIT I:
Four things:
I've read up on
CursorAdapter
s and it looks like you want to overridebindView()
instead ofgetView()
. It looks likegetView()
is called twice for each row that's to be displayed and this is somehow preventing the cursor from being updated and thus always points to the first row. I think this is why yourListView
only displays the first row. Further, the defaultCursorAdapter
implementation for a ListView will recycle views for you, so overridinggetView()
really isn't necessary (check out this answer for more info).When creating your
mAdapter
, you should pass a nullCursor
into the constructor. TheCursor
will be delivered inonLoadFinished
(when theLoader
has finished the query) and will be bound to the adapter withswapCursor(cursor)
.Your
onCreateLoader()
method will create (or start) theLoader
that will perform the initial query. Make sure it looks something like this,@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; }
Make sure you make use of the correct
SimpleCursorAdapter
constructor... the one you are currently using is deprecated! (pass0
as a flag... theCursorLoader
will register a content observer for you so you don't need to pass in anything special).
EDIT II:
To clarify, the bindView()
method is where you populate your row's widgets with the data from the Cursor
's current position. You are handed the Cursor
pre-positioned at the proper row. You need to pull data out of the Cursor
and pour it into your desired widgets. In other words, you'll need to query for the row's id (instead of using the "position" argument in getView()
). Try setting the onClickListener
in bindView()
with something like:
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. */
}
});
这篇关于光标不与自定义适配器正确文本装订的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!