自定义ListView newView问题

时间:2012-02-02 03:20:01

标签: android listview

简而言之,没有为每个列表项调用newView,这里是log:

01-06 20:04:15.957: D/NoteListActivity(2771): newView Note ID:12
01-06 20:04:16.087: D/NoteItemView(2771): updateActionText Note ID:12 Action:Stamp
01-06 20:04:16.117: D/NoteListActivity(2771): bindView Note ID:12
01-06 20:04:16.329: D/NoteListActivity(2771): newView Note ID:13
01-06 20:04:16.477: D/NoteItemView(2771): updateActionText Note ID:13 Action:Stamp
01-06 20:04:16.497: D/NoteListActivity(2771): bindView Note ID:13
01-06 20:04:16.729: D/NoteListActivity(2771): newView Note ID:14
01-06 20:04:16.867: D/NoteItemView(2771): updateActionText Note ID:14 Action:Stamp
01-06 20:04:16.887: D/NoteListActivity(2771): bindView Note ID:14
01-06 20:04:17.107: D/NoteListActivity(2771): newView Note ID:15
01-06 20:04:17.247: D/NoteItemView(2771): updateActionText Note ID:15 Action:Stamp
01-06 20:04:17.269: D/NoteListActivity(2771): bindView Note ID:15
01-06 20:04:17.487: D/NoteListActivity(2771): newView Note ID:16
01-06 20:04:17.639: D/NoteItemView(2771): updateActionText Note ID:16 Action:Stamp
01-06 20:04:17.657: D/NoteListActivity(2771): bindView Note ID:16
01-06 20:04:17.897: D/NoteListActivity(2771): newView Note ID:17
01-06 20:04:18.007: D/dalvikvm(2771): GC_EXTERNAL_ALLOC freed 99K, 47% free 2902K/5447K, external 2888K/2971K, paused 53ms
01-06 20:04:18.127: D/NoteItemView(2771): updateActionText Note ID:17 Action:Count
01-06 20:04:18.147: D/NoteListActivity(2771): bindView Note ID:17
01-06 20:04:18.367: D/NoteListActivity(2771): newView Note ID:18
01-06 20:04:18.517: D/NoteItemView(2771): updateActionText Note ID:18 Action:Stamp
01-06 20:04:18.537: D/NoteListActivity(2771): bindView Note ID:18
01-06 20:04:36.488: W/KeyCharacterMap(2771): No keyboard for id 0
01-06 20:04:36.488: W/KeyCharacterMap(2771): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
01-06 20:04:38.118: D/NoteListActivity(2771): newView Note ID:19
01-06 20:04:38.257: D/NoteItemView(2771): updateActionText Note ID:19 Action:Stamp
01-06 20:04:38.277: D/NoteListActivity(2771): bindView Note ID:19
01-06 20:04:38.767: D/NoteListActivity(2771): newView Note ID:20
01-06 20:04:38.849: D/NoteItemView(2771): updateActionText Note ID:20 Action:Stamp
01-06 20:04:38.867: D/NoteListActivity(2771): bindView Note ID:20
01-06 20:04:39.327: D/NoteItemView(2771): updateActionText Note ID:12 Action:Stamp
01-06 20:04:39.347: D/NoteListActivity(2771): bindView Note ID:21
01-06 20:04:39.857: D/dalvikvm(2771): GC_EXTERNAL_ALLOC freed 84K, 47% free 2944K/5511K, external 3593K/3852K, paused 59ms
01-06 20:04:39.997: D/NoteItemView(2771): updateActionText Note ID:13 Action:Stamp
01-06 20:04:40.017: D/NoteListActivity(2771): bindView Note ID:22
01-06 20:04:40.537: D/NoteItemView(2771): updateActionText Note ID:14 Action:Stamp
01-06 20:04:40.557: D/NoteListActivity(2771): bindView Note ID:23
01-06 20:04:41.087: D/NoteItemView(2771): updateActionText Note ID:15 Action:Stamp
01-06 20:04:41.107: D/NoteListActivity(2771): bindView Note ID:24
01-06 20:04:41.617: D/NoteItemView(2771): updateActionText Note ID:16 Action:Stamp
01-06 20:04:41.639: D/NoteListActivity(2771): bindView Note ID:25
01-06 20:06:23.858: D/NoteItemView(2771): updateActionText Note ID:18 Action:Stamp
01-06 20:06:23.878: D/NoteListActivity(2771): bindView Note ID:18
01-06 20:06:24.267: D/dalvikvm(2771): GC_EXTERNAL_ALLOC freed 79K, 47% free 2944K/5511K, external 4681K/4733K, paused 53ms
01-06 20:06:26.519: D/NoteItemView(2771): updateActionText Note ID:15 Action:Stamp
01-06 20:06:26.537: D/NoteListActivity(2771): bindView Note ID:17
01-06 20:06:26.927: D/dalvikvm(2771): GC_EXTERNAL_ALLOC freed 17K, 47% free 2944K/5511K, external 5020K/5295K, paused 60ms
01-06 20:06:26.987: D/NoteItemView(2771): updateActionText Note ID:12 Action:Stamp
01-06 20:06:27.008: D/NoteListActivity(2771): bindView Note ID:16
01-06 20:06:27.247: D/NoteItemView(2771): updateActionText Note ID:13 Action:Stamp
01-06 20:06:27.267: D/NoteListActivity(2771): bindView Note ID:15
01-06 20:06:27.517: D/NoteItemView(2771): updateActionText Note ID:14 Action:Stamp
01-06 20:06:27.537: D/NoteListActivity(2771): bindView Note ID:14
01-06 20:06:28.397: D/NoteItemView(2771): updateActionText Note ID:16 Action:Stamp
01-06 20:06:28.417: D/NoteListActivity(2771): bindView Note ID:13
01-06 20:06:28.809: D/NoteItemView(2771): updateActionText Note ID:19 Action:Stamp
01-06 20:06:28.837: D/NoteListActivity(2771): bindView Note ID:12
01-06 20:06:29.167: D/NoteItemView(2771): updateActionText Note ID:12 Action:Stamp
01-06 20:06:29.189: D/NoteListActivity(2771): bindView Note ID:16
01-06 20:06:29.477: D/NoteItemView(2771): updateActionText Note ID:15 Action:Stamp
01-06 20:06:29.497: D/NoteListActivity(2771): bindView Note ID:17
01-06 20:06:29.688: D/NoteItemView(2771): updateActionText Note ID:18 Action:Stamp
01-06 20:06:29.707: D/NoteListActivity(2771): bindView Note ID:18
01-06 20:06:31.807: D/NoteItemView(2771): updateActionText Note ID:20 Action:Stamp
01-06 20:06:31.827: D/NoteListActivity(2771): bindView Note ID:19
01-06 20:06:32.267: D/NoteItemView(2771): updateActionText Note ID:13 Action:Stamp
01-06 20:06:32.288: D/NoteListActivity(2771): bindView Note ID:20
01-06 20:06:32.537: D/NoteItemView(2771): updateActionText Note ID:14 Action:Stamp
01-06 20:06:32.567: D/NoteListActivity(2771): bindView Note ID:21
01-06 20:06:32.867: D/NoteItemView(2771): updateActionText Note ID:16 Action:Stamp
01-06 20:06:32.887: D/NoteListActivity(2771): bindView Note ID:22
01-06 20:06:33.127: D/NoteItemView(2771): updateActionText Note ID:19 Action:Stamp
01-06 20:06:33.147: D/NoteListActivity(2771): bindView Note ID:23
01-06 20:06:33.677: D/NoteItemView(2771): updateActionText Note ID:15 Action:Stamp
01-06 20:06:33.697: D/NoteListActivity(2771): bindView Note ID:24
01-06 20:06:34.187: D/NoteItemView(2771): updateActionText Note ID:14 Action:Stamp
01-06 20:06:34.207: D/NoteListActivity(2771): bindView Note ID:25
01-06 20:06:34.447: D/NoteItemView(2771): updateActionText Note ID:13 Action:Stamp
01-06 20:06:34.467: D/NoteListActivity(2771): bindView Note ID:21
01-06 20:06:34.647: D/NoteItemView(2771): updateActionText Note ID:20 Action:Stamp
01-06 20:06:34.667: D/NoteListActivity(2771): bindView Note ID:20
01-06 20:06:34.847: D/NoteItemView(2771): updateActionText Note ID:18 Action:Stamp
01-06 20:06:34.867: D/NoteListActivity(2771): bindView Note ID:19

这是适配器:

class NoteItemAdapter extends CursorAdapter {

    private LayoutInflater mInflater;

    public NoteItemAdapter(Context context, Cursor c) {
        super(context, c);
        mInflater = LayoutInflater.from(context);
    }

    public NoteItemAdapter(Context context, Cursor c, boolean autoRequery) {
        super(context, c, autoRequery);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        final NoteListItemHolder noteItemHolder = (NoteListItemHolder)view.getTag();
        NoteCursor nc = (NoteCursor)cursor;

        initView(noteItemHolder, nc);

        Log.d(TAG, String.format("bindView Note ID:%s", nc.getColId()));
    }

    private void initView(final NoteListItemHolder noteItemHolder, NoteCursor nc)
            throws NotFoundException {
        noteItemHolder.getBase().setClickable(false);
        noteItemHolder.getBase().setLongClickable(true);
        noteItemHolder.getTopText().setText(nc.getColTitle());
        noteItemHolder.getBottomText().setText(nc.getColNote());
        byte[] icon = nc.getColActionIcon();
        if (icon != null) {
            noteItemHolder.getIconButton().setImageBitmap(BitmapUtil.BitmapFromByteArray(icon));
        } else {
            NoteAction actionType = NoteListItemHolder.NoteActionFromInt(nc.getColActionType());
            int actionIconResId = R.drawable.note_action_icon_none;
            switch (actionType) {
            case Span:
                actionIconResId = R.drawable.note_action_icon_span;
                break;
            case Stamp:
                actionIconResId = R.drawable.note_action_icon_stamp;
                break;
            case Count:
                actionIconResId = R.drawable.note_action_icon_count;
                break;
            default:
                //NOOP
                break;
            }
            noteItemHolder.getIconButton().setImageBitmap(((BitmapDrawable)getResources().getDrawable(actionIconResId)).getBitmap());
        }
        noteItemHolder.getIconButton().setClickable(true);
        noteItemHolder.getIconButton().setLongClickable(false);
        noteItemHolder.updateActionText();

        noteItemHolder.getIconButton().setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View iconView) {
                noteItemHolder.doAction();
            }
        });
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
        View row = mInflater.inflate(R.layout.note_list_item, viewGroup, false);
        NoteCursor nc = (NoteCursor)getCursor();
        NoteListItemHolder wrapper = new NoteListItemHolder(row, nc.getColId());
        row.setTag(wrapper);

        Log.d(TAG, String.format("newView Note ID:%s", nc.getColId()));

        return row;
    }
}

我一直在阅读有关类似问题的一堆内容,我无法弄明白!

项目的第一页(加载列表视图时可见)始终是正确的,但是当您滚动时,列表项的至少一个文本视图始终是正确的,并且新项目中至少有一个总是错误的(两个文本视图都是从始终调用的bindView更新文本)。这让我相信问题不在适配器中,但是正如日志所示,newView不会被调用21和更高的项目。

并且...为了额外的奖励,当你向后滚动时,正确的那些不再是;他们现在表现得像列表的其余部分。

那么,任何想法的家伙?

2 个答案:

答案 0 :(得分:2)

这是预期的。 CursorAdapter只是为您回收视图。只会在第一个屏幕(可能还有几个项目)中调用newView(),但对于所有其他视图,您在newView()中返回的视图将被回收,并且只会通过{{ 1}}方法。在这些情况下的问题通常是其中一个字段没有返回到“默认”状态并且过时的数据透过。这就是你有“不正确”数据的原因。在我发布的bindView()代码中,我看不出任何明显错误,但如果我不得不猜测,我会说问题出在bindView()方法中。

答案 1 :(得分:-1)

正如@dmon指出的那样,这些观点正在被重用(是的,我知道我现在应该已经得到了这个概念)。在我的持有者中,注释ID以及其他内容被存储并随后用于填充一些子视图。仅供参考我正在将这些列表项目归结为持有者模式,并且想到为什么不将文本更新放在那里,因为我将缓存数据 - 然后是BOOM!

既然我明白视图并不总是显示相同的数据,我已经删除了那个逻辑,一切都很棒!

非常感谢@dmon解释这个我无法掌握的概念(希望这也有助于其他一些无望的代码猴子)!

以下是更改的行(我现在只是将注释ID传递给持有者):

noteItemHolder.updateActionText();
//is now

noteItemHolder.updateActionText(noteID);

noteItemHolder.doAction();
//is now

noteItemHolder.doAction(noteID);