2013-02-03 43 views
0

问题:我试图使用自定义ListView在聊天中显示消息。我用我自己班的对象参数化了ArrayList,代码如下。android自定义ListView - 试图了解getView()如何工作

问题:消息文本和时间戳总是保持不变,每次布局膨胀时,getView()方法中的某些错误,但我无法弄清楚什么。

P.S. ChatActivity包含很多代码,我只会发布与问题相关的事情以保持清洁。

Message.java:

public class Message{ 

/* 
* 1- outgoing 
* 2-incoming 
* */ 

public String message; 
public String timestamp; 
public TextView tvmessage, tvtimestamp; 
public ImageView indicator; 
public int type; 

public Message(String text, int type){ 
    this.timestamp = generateTimestamp(); 
    this.message = text; 
    this.type=type; 

    Log.d("Message", message); 
    //Message text is set correctly each time the constructor is called 

} 

@SuppressLint("SimpleDateFormat") 
public String generateTimestamp() { 
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); 
    String ts = sdf.format(new Date()); 

    return ts; 
} 

    } 

ChatActivity:

private ArrayList<Message> OutgoingMessagesList; 
private SingleChatAdapter adapter; 
    private EditText etInput; 
lv = getListView(); 
    adapter = new SingleChatAdapter(this, OutgoingMessagesList); 
    lv.setAdapter(adapter); 

public void sendMessage() { 

    String tmpMessage = etInput.getText().toString().trim(); 
    /*--- check whether the message string is empty ---*/ 
    if (tmpMessage.length() > 0) { 

     Message msg = new Message(tmpMessage, 1); 

     OutgoingMessagesList.add(msg); 

     /* 
     * TODO: save the message to local database, send the message to 
     * server, save it to server database and forward to the recipient 
     */ 
     adapter.notifyDataSetChanged(); 
     etInput.setText(""); 

    } else { 

     MiscUtils.gibShortToast(this, getString(R.string.msgEmpty)); 
    } 

} 

适配器类,我认为这个问题是:从我的Message类

public final class SingleChatAdapter extends BaseAdapter { 
private Context context; 
Message msg; 
private ArrayList<Message> messages; 

public SingleChatAdapter(Context context, ArrayList<Message> chat) { 

    this.context = context; 
    this.messages = chat; 
    Log.d("ChatAdapter", "called constructor"); 

} 

public int getCount() { 
    return messages.size(); 
} 

public Object getItem(int position) { 
    return messages.get(position); 
} 

public long getItemId(int position) { 
    return position; 
} 

public View getView(int position, View convertView, ViewGroup viewGroup) { 

    msg = (Message) getItem(position); 

    if (convertView == null) { 

     LayoutInflater inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     // TODO message_incoming should be inflated for messages received 
     // from server 
     convertView = (LinearLayout) inflater.inflate(
       R.layout.message_outgoing, null); 

     convertView.setTag(msg); 

    } else { 

     msg = (Message) convertView.getTag(); 

    } 

    msg.tvmessage = (TextView) convertView 
      .findViewById(R.id.tvMessageOutgoing); 
    msg.tvtimestamp = (TextView) convertView.findViewById(R.id.tvTimestamp); 
    msg.indicator = (ImageView) convertView 
      .findViewById(R.id.imgMessageState); 

    msg.tvmessage.setText(msg.message); 

    msg.tvtimestamp.setText(msg.timestamp); 

    return convertView; 
} 

消息字符串包含正确的每次都会有一个值,但是充值到列表中的文本总是保持不变。我错过了什么?如果你想了解的ListView作品和getView如何引用this聊罗马盖伊也是一个不错的博客文章

+0

你有没有尝试删除else语句(内getView一)中提到? –

回答

3

您应该删除else语句(内getView的一个),因为现在是这样工作的: 如果convertView为null(创建listView的第一项),那么它会被夸大,并将您的消息设置为该视图的标记。但是当创建下一个项目时,convertView不再为null,并且您的else语句被调用。所以你的消息被替换为一个保存为convertView的标签。

你也应该看录像孔子:)

+0

+1,它告诉我们只有当列表视图中没有项目时,convertview才为null。 –