我有一个ChatActivity,可通过CursorLoader加载其数据。 CursorLoader返回带有两个寄存器的游标,但是从不调用适配器中的newView和bindView方法。

我的活动

public class ChatActivity extends BaseActivity implements LoaderManager.LoaderCallbacks<Cursor> {

    public static final String EXTRA_AMANTEID = "amanteId";

    private EditText messageET;
    private ListView messagesContainer;
    private Button sendBtn;
    private ChatAdapter adapter;
    private Long amanteId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        amanteId = getIntent().getLongExtra(ChatActivity.EXTRA_AMANTEID, 0L);

        messagesContainer = (ListView) findViewById(R.id.messagesContainer);
        messageET = (EditText) findViewById(R.id.messageEdit);
        sendBtn = (Button) findViewById(R.id.chatSendButton);

        RelativeLayout container = (RelativeLayout) findViewById(R.id.container);

        adapter = new ChatAdapter(this);
        getLoaderManager().initLoader(0, null, this);
        messagesContainer.setAdapter(adapter);
    }

    private void scroll() {
        messagesContainer.setSelection(messagesContainer.getCount() - 1);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        return new CursorLoader(ChatActivity.this, MensagemProvider.CONTENT_URI_CONVERSA, null, null, new String[]{Long.toString(amanteId), Long.toString(amanteId)}, null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        adapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        adapter.swapCursor(null);
    }
}


我的适配器

public class ChatAdapter extends CursorAdapter {

    private Cursor cursor;
    private int dataEnvioColumnIndex;
    private int idMensagemColumnIndex;
    private int idRemetenteColumnIndex;
    private int idDestinatarioColumnIndex;
    private int apelidoRemetenteColumnIndex;
    private int apelidoDestinatarioColumnIndex;
    private int textoMensagemColumnIndex;
    private long idColaboradorLogado;

    public ChatAdapter(Context context) {
        super(context, null, false);
    }

    public ChatMessage getItem() {
        ChatMessage message = new ChatMessage();
        SimpleDateFormat dt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        Date dataEnvio = new Date(cursor.getLong(dataEnvioColumnIndex));
        message.setDate(dt.format(dataEnvio));
        message.setId(cursor.getLong(idMensagemColumnIndex));
        Long de = cursor.getLong(idRemetenteColumnIndex);
        Long logado = BaseApp.getCredentials().getId();
        message.setMe(de.equals(logado));
        message.setMessage(cursor.getString(textoMensagemColumnIndex));
        return message;
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View retView = vi.inflate(R.layout.list_item_chat_message, null);
        return retView;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = createViewHolder(view);;
        view.setTag(holder);
        ChatMessage chatMessage = getItem();
        boolean myMsg = chatMessage.getIsme() ;//Just a dummy check
        holder.txtMessage.setText(chatMessage.getMessage());
        holder.txtInfo.setText(chatMessage.getDate());
    }

    private ViewHolder createViewHolder(View v) {
        ViewHolder holder = new ViewHolder();
        holder.txtMessage = (TextView) v.findViewById(R.id.txtMessage);
        holder.content = (LinearLayout) v.findViewById(R.id.content);
        holder.contentWithBG = (LinearLayout) v.findViewById(R.id.contentWithBackground);
        holder.txtInfo = (TextView) v.findViewById(R.id.txtInfo);
        return holder;
    }


    private static class ViewHolder {
        public TextView txtMessage;
        public TextView txtInfo;
        public LinearLayout content;
        public LinearLayout contentWithBG;
    }

    @Override
    public Cursor swapCursor(Cursor cursor) {
        if(cursor!=null) {
            cursor.moveToFirst();
            idMensagemColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_MENSAGEMID);
            idRemetenteColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_DE);
            idDestinatarioColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_PARA);
            apelidoRemetenteColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_APELIDO_REMETENTE);
            apelidoDestinatarioColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_APELIDO_DESTINATARIO);
            textoMensagemColumnIndex = cursor.getColumnIndex(MensagemProvider.COLUMN_MENSAGEM);
        }
        notifyDataSetChanged();

        return cursor;
    }
}


我做错了什么?有谁能够帮助我 ?
谢谢!

最佳答案

覆盖swapCursor()表示麻烦。游标将不会被放置在适配器期望放置的位置(首先)。而且您不会调用super.swapCursor(),因此适配器永远不会真正听到有关新光标的消息。

我敢打赌,您试图通过每次交换新游标仅获取一次列索引来“优化”。

首先,只需尝试摆脱swapCursor()覆盖并在getColumnIndex()方法中进行getItem()调用。如果该方法有效,并且您仍然真的希望每个游标只调用一次getColumnIndex(),则可以尝试进行以下操作,例如在交换游标时将所有游标索引设置为-1,然后仅在getColumnIndex()内调用getItem()索引是-1。

但是不要弄乱swapCursor(),尤其是在不调用super.swapCursor()并返回其结果的情况下。

10-07 22:46