【问题标题】:Why my listview adapter doesn't show the right layout on new view?为什么我的列表视图适配器没有在新视图上显示正确的布局?
【发布时间】:2012-07-19 19:03:12
【问题描述】:

我有一个自定义光标适配器,它基于 android 中的 MMS 和 SMS 数据库。代码如下所示:

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    Message m = Message.getMessage(context, cursor); // gets message from cursor
    int t = m.getType(); // this gets the type of message it is .. 2 = recv, 1 = sent

    switch(t){
    case Message.MMS_IN: // 128
        return mInflater.inflate(R.layout.messagelist_item_recv, parent, false);
    case Message.MMS_OUT: // 132
        return mInflater.inflate(R.layout.messagelist_item_sent, parent, false);
    case Message.SMS_IN: // 2
        return mInflater.inflate(R.layout.messagelist_item_recv, parent, false);
    case Message.SMS_OUT: // 1
        return mInflater.inflate(R.layout.messagelist_item_sent, parent, false);
    default:
        return null;
    }
}

R.layout.messagelist_item_sent 用于发送消息,R.layout.messagelist_item_recv 用于接收消息。 但是查看我的消息,当列表视图正确显示时首先显示的行,但是当我将列表视图上升到新视图时,布局混淆了。 recv 布局是发送的布局应该位于的位置,反之亦然。有谁知道为什么会出现这种问题?

* 编辑 **

@Override
public int getItemViewType(int position) {
     // move the cursor to the position
Cursor c = (Cursor)getItem(position);
Message m = Message.getMessage(context, c);

if (isInbox(m.getType())){
   inflater.inflate(recv view);
 // it's been shortened 
} else {
   inflater.inflate(send view);   
// and determine the correct type of row layout
     // return 0 or 1
     // use the code that you currently have from the newView method
}

【问题讨论】:

  • 您是否也尝试过覆盖getView(...)ListView 中的项目在滚动时会被回收。例如,如果列表只能显示 10 个项目,那么只会创建 10 个项目视图。随着列表滚动,任何给定位置的上一个项目视图都作为convertView 参数传递给getView 方法。然后,您将使用现有的 convertView 并将其添加到您需要的任何列表项布局中。
  • 感谢您的提示。那么代码到底是什么样的呢?在 getView(...) 代码中,我会检查 convertView 是否为空,如果是,则检查消息类型,然后再次膨胀视图?

标签: java android


【解决方案1】:

但是查看我的消息,当 listview 显示正确,但是当我将 listview 上移到新的 视图,布局混淆了。

这可能是因为您没有正确处理ListView 回收机制。不会为每一行调用 newView 方法,当没有用于行布局的回收视图时调用它(就像第一次显示 ListView 时,这就是为什么行以正确的顺序出现的原因) .否则,ListView 将使用回收的视图,它可能是也可能不是正确的视图类型。

您应该使用getViewTypeCount()getItemViewType() 方法。方法getViewTypeCount() 将返回两个(因为您有两种类型的行?!?)然后在getItemViewType 中实现确定正确行类型的逻辑:

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
     Cursor c = (Cursor)getItem(position);
     Message m = Message.getMessage(context, c);
     switch(m.getType()){
         case Message.MMS_IN: // 128
             return 1;
         case Message.MMS_OUT: // 132
             return 0;
         case Message.SMS_IN: // 2
             return 1;
         case Message.SMS_OUT: // 1
             return 0;
         default:
             return 0;
      }
}

然后在newView方法中:

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    int rowType = getItemViewType(cursor.getPosition());
    if (rowType == 0){
        return mInflater.inflate(R.layout.messagelist_item_sent, parent, false);
    } else if (rowType == 1){    
        return mInflater.inflate(R.layout.messagelist_item_recv, parent, false);
    } else {
        return null;
    }
}

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2019-09-21
    • 2015-10-15
    相关资源
    最近更新 更多