android - 光标未使用自定义适配器正确绑定(bind)文本

标签 android android-listview android-cursoradapter android-loadermanager android-cursor

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() 中,但不能同时放在两者中。


编辑一:

四件事:

  1. 我已经阅读了有关 CursorAdapter 的内容,看起来您想覆盖 bindView() 而不是 getView()。看起来 getView() 为要显示的每一行调用了两次,这在某种程度上阻止了光标更新,因此始终指向第一行。我认为这就是为什么您的 ListView 只显示第一行的原因。此外,ListView 的默认 CursorAdapter 实现将为您回收 View ,因此实际上不需要覆盖 getView()(查看此 answer 了解更多信息) .

  2. 在创建 mAdapter 时,您应该将一个空的 Cursor 传递给构造函数。 Cursor 将在 onLoadFinished 中传递(当 Loader 完成查询时),并使用 swapCursor(光标)

  3. 您的 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;
    }
    
  4. 确保您使用了正确的 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/

相关文章:

android - 如何在模拟器上测试触摸事件

java - 将音频文件和值从 Android 发送到服务器

android - 如何使 listview 和 GridLayout 可滚动

Android:可以将参数从 CursorAdapter 传递到服务

android - 必须在 notifyItemInserted 之后调用

android - 寻找角色的坐标?

android - ListView 在滚动时搞砸了

Android 应用程序崩溃 : Parsing JSON into ListView

带有自定义 BaseAdapter 的 Android CursorLoaded

android - EditText 在 CursorAdapter 中点击改变我的 View