更新在getView中执行请求的自定义CursorAdapter失败

时间:2012-03-28 09:51:40

标签: android android-listview android-cursoradapter

我仍然没有确切地知道自定义CursorAdapter应该如何工作,所以经过艰苦的尝试,这就是事情:

  1. 我在getView()内的按钮上实现了一个监听器。
  2. 侦听器启动删除行事件。
  3. 为了实现它,我使用单例数据库,我可以在这里执行所有类的请求(实际上是单例的目的)
  4. 我通常从活动类更新(插入和修改),所以我只需要获取新的数据库游标并将其重新分配给新的CursorAdapter,我将其自身重新分配给{{ 1}}。
  5. 这里有所不同:我在ListView方法的CursorAdapter类中,我不知道如何从内部更新我的适配器。
  6. 对于那些不想阅读我无聊解释的人,这里是ListView的代码:

    getView

    启动删除事件时出现以下错误:

        @Override
    public View getView(int position, View convertView, ViewGroup parent){
        convertViewParam = convertView;
        ViewHolder viewHolder = new ViewHolder();
        if (convertViewParam == null) {
            int type = getItemViewType(position);
            switch (type) {
    
            case TYPE_ADD_NOTE_TOP:
                convertViewParam = inflater.inflate(R.layout.add_note_top, null);
                viewHolder.contentNote = (EditText)convertViewParam.findViewById(R.id.add_note_top_id);
                break;
            case TYPE_ITEM:
                convertViewParam = inflater.inflate(R.layout.row_note, null);
                viewHolder.delete = (Button)convertViewParam.findViewById(R.id.delete);
                if (deleteMode){
                    viewHolder.delete.setVisibility(View.VISIBLE);
                }else{
                    viewHolder.delete.setVisibility(View.GONE);
                }
    
                viewHolder.contentNote = (TextView)convertViewParam.findViewById(R.id.note);
    
                getCursor().moveToPosition(position - 1);
                int currentPosition = getCursor().getPosition();
                Cursor c = getCursor();
                c.moveToPosition(currentPosition);
    
                ((TextView) viewHolder.contentNote).setText(c.getString(c.getColumnIndex("content_note")));
                int rowId = c.getInt(c.getColumnIndex("_id"));
    
                viewHolder.delete.setTag(new Integer(rowId));
                viewHolder.contentNote.setTag(new Integer(rowId));
    
                OnClickListener listener = new OnClickListener() {
    
                    @Override
                    public void onClick(View v) {
                        int thePosition = (Integer) v.getTag();
    
                        int posCurs = notesCursorAdapter.getCursor().getPosition();
                        NoteDataSource.getSingletonObject(context).deleteNote(thePosition, context);
                        notesCursorAdapter.changeCursor(NoteDataSource.getSingletonObject(context).getAllNotes());
                        notesCursorAdapter.notifyDataSetChanged();
    
                    }
                };
                viewHolder.delete.setOnClickListener(listener);
    
                break;
    
            case TYPE_ADD_NOTE_BOTTOM:
                convertViewParam = inflater.inflate(R.layout.add_note_bottom, null);
                LinearLayout linearLayout = (LinearLayout)convertViewParam.findViewById(R.id.bottomLayout);
                linearLayout.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
    
                    }
                });
                break;
            }
            convertViewParam.setTag(viewHolder);
        } else {
    
            viewHolder = (ViewHolder)convertViewParam.getTag();
            if (viewHolder.contentNote!=null){
                if (viewHolder.contentNote.getTag() == convertViewParam.findViewById(R.id.note)){
                    int test = (Integer) viewHolder.delete.getTag();
                    System.out.println("current tag " + test);
                    String txt = getCursor().getString(getCursor().getColumnIndex("content_note"));
                    ((TextView) viewHolder.contentNote).setText(txt);
                }
            }
    
    
        }
    
        return convertViewParam;
    }
    

    如果您想要更多信息,请询问。

    我正在寻找错误修复或只是解释,谢谢。

2 个答案:

答案 0 :(得分:2)

这是一份写得很好的问题陈述。我遇到了这个问题并且对此我的头脑。试试这个。

  • 在你的适配器中创建一个类似
  • 的监听器
public interface ItemDeletedListener(){
    public void itemDeleted(int position);
}
  • 在适配器m_listener中创建ItemDeletedListener的实例。

  • 编写一个setter函数,setItemDeletedListener(ItemDeletedListener listener){}

  • 在你的getView(),onClickListener中,调用m_listener并传递需要删除的位置。

现在,在您的活动中,执行以下操作。

  1. 实现您在上面创建的侦听器。
  2. 在您的实现中,执行删除工作,然后在那里执行changeCursor()。

答案 1 :(得分:1)

了解您获得异常的哪一行会有所帮助。首先,一件坏事是你根据位置int从数据库中删除了一个注释,之后你再次获取所有数据并将该光标上的位置移动到上一个删除的位置。

如果您在数据库中有3个注释(并在列表中显示它们),并且您想删除最后一个注释,则会发生这种情况:

  • thePosition将为2
  • 删除记事
  • 再次获取数据库中的所有注释(光标现在有2行,因为你删除了一行)
  • 将光标移至thePosition(值2)
  • 游标只有2行(从0开始编号),你要求的行号为2
  • 例外

如果您要删除记事,请将该行的_id作为标记传递并使用该标记删除该记事:

Cursor c = getCursor();
c.moveToPosition(position); 
long rowId = c.getLong(c.getColumnIndex("_id"));
viewHolder.delete.setTag(new Long(rowId));

然后在onClick()方法中使用它来删除注释并停止弄乱光标上的moveToPosition()