为什么我的listview适配器在新视图上没有显示正确的布局?

And*_*ler 0 java android

我有一个自定义的光标适配器,它基于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

Luk*_*rog 5

但是查看我的消息,列表视图正确显示时首先显示的行,但是当我将列表视图上移到新视图时,布局会混淆.

这可能是因为您没有正确处理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;
      }
}
Run Code Online (Sandbox Code Playgroud)

然后在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;
    }
}
Run Code Online (Sandbox Code Playgroud)