我正在尝试根据以下文章提出一个简单的聊天应用程序:
http://www.codeproject.com/Tips/897826/Designing-Android-Chat-Bubble-Chat-UI
我设法使我的聊天工作正常,
这是我的一系列事件......
向MySql Db发送新消息并返回一个JSON,其状态为消息已发送,然后我将GCM消息发送到正在为广播接收者列出的恢复设备,并触发一个功能以添加新消息。所有这一切都很好,花花公子,一旦消息从服务器下载,我将GCM发送回发送方以通知消息已被读取。这就是我陷入困境的地方:(
如何更新已填充的列表视图以显示更改?
类似于:
// Do a JSON call for the current user
No Problem here
// See if the status has changed
???????????????
//Do the Update
??????????????
update (Int msgID){
// here i need to update the imageview
notifyDataSetChanged();
}
请参阅下面的基本代码。
ChatActivity
public class ChatActivity extends ActionBarActivity {
private EditText messageET;
private ListView messagesContainer;
private Button sendBtn;
private ChatAdapter adapter;
private ArrayList<ChatMessage> chatHistory;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
initControls();
}
private void initControls() {
messagesContainer = (ListView) findViewById(R.id.messagesContainer);
messageET = (EditText) findViewById(R.id.messageEdit);
sendBtn = (Button) findViewById(R.id.chatSendButton);
TextView meLabel = (TextView) findViewById(R.id.meLbl);
TextView companionLabel = (TextView) findViewById(R.id.friendLabel);
RelativeLayout container = (RelativeLayout) findViewById(R.id.container);
companionLabel.setText("My Buddy");// Hard Coded
loadDummyHistory();
sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String messageText = messageET.getText().toString();
if (TextUtils.isEmpty(messageText)) {
return;
}
ChatMessage chatMessage = new ChatMessage();
chatMessage.setId(122);//dummy
chatMessage.setMessage(messageText);
chatMessage.setDate(DateFormat.getDateTimeInstance().format(new Date()));
chatMessage.setMe(true);
messageET.setText("");
displayMessage(chatMessage);
}
});
}
public void displayMessage(ChatMessage message) {
adapter.add(message);
adapter.notifyDataSetChanged();
scroll();
}
private void scroll() {
messagesContainer.setSelection(messagesContainer.getCount() - 1);
}
private void loadDummyHistory(){
chatHistory = new ArrayList<ChatMessage>();
ChatMessage msg = new ChatMessage();
msg.setId(1);
msg.setMe(false);
msg.setMessage("Hi");
msg.setDate(DateFormat.getDateTimeInstance().format(new Date()));
chatHistory.add(msg);
ChatMessage msg1 = new ChatMessage();
msg1.setId(2);
msg1.setMe(false);
msg1.setMessage("How r u doing???");
msg1.setDate(DateFormat.getDateTimeInstance().format(new Date()));
chatHistory.add(msg1);
adapter = new ChatAdapter(ChatActivity.this, new ArrayList<ChatMessage>());
messagesContainer.setAdapter(adapter);
for(int i=0; i<chatHistory.size(); i++) {
ChatMessage message = chatHistory.get(i);
displayMessage(message);
}
}
}
ChatMessage
public class ChatMessage {
private long id;
private boolean isMe;
private String message;
private Long userId;
private String dateTime;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public boolean getIsme() {
return isMe;
}
public void setMe(boolean isMe) {
this.isMe = isMe;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public String getDate() {
return dateTime;
}
public void setDate(String dateTime) {
this.dateTime = dateTime;
}
}
ChatAdapter
public class ChatAdapter extends BaseAdapter {
private final List<ChatMessage> chatMessages;
private Activity context;
public ChatAdapter(Activity context, List<ChatMessage> chatMessages) {
this.context = context;
this.chatMessages = chatMessages;
}
@Override
public int getCount() {
if (chatMessages != null) {
return chatMessages.size();
} else {
return 0;
}
}
@Override
public ChatMessage getItem(int position) {
if (chatMessages != null) {
return chatMessages.get(position);
} else {
return null;
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
ChatMessage chatMessage = getItem(position);
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = vi.inflate(R.layout.list_item_chat_message, null);
holder = createViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
boolean myMsg = chatMessage.getIsme() ;//Just a dummy check
//to simulate whether it me or other sender
setAlignment(holder, myMsg);
holder.txtMessage.setText(chatMessage.getMessage());
holder.txtInfo.setText(chatMessage.getDate());
return convertView;
}
public void add(ChatMessage message) {
chatMessages.add(message);
}
public void add(List<ChatMessage> messages) {
chatMessages.addAll(messages);
}
private void setAlignment(ViewHolder holder, boolean isMe) {
if (!isMe) {
holder.contentWithBG.setBackgroundResource(R.drawable.in_message_bg);
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams) holder.contentWithBG.getLayoutParams();
layoutParams.gravity = Gravity.RIGHT;
holder.contentWithBG.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams lp =
(RelativeLayout.LayoutParams) holder.content.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
holder.content.setLayoutParams(lp);
layoutParams = (LinearLayout.LayoutParams) holder.txtMessage.getLayoutParams();
layoutParams.gravity = Gravity.RIGHT;
holder.txtMessage.setLayoutParams(layoutParams);
layoutParams = (LinearLayout.LayoutParams) holder.txtInfo.getLayoutParams();
layoutParams.gravity = Gravity.RIGHT;
holder.txtInfo.setLayoutParams(layoutParams);
} else {
holder.contentWithBG.setBackgroundResource(R.drawable.out_message_bg);
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams) holder.contentWithBG.getLayoutParams();
layoutParams.gravity = Gravity.LEFT;
holder.contentWithBG.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams lp =
(RelativeLayout.LayoutParams) holder.content.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
holder.content.setLayoutParams(lp);
layoutParams = (LinearLayout.LayoutParams) holder.txtMessage.getLayoutParams();
layoutParams.gravity = Gravity.LEFT;
holder.txtMessage.setLayoutParams(layoutParams);
layoutParams = (LinearLayout.LayoutParams) holder.txtInfo.getLayoutParams();
layoutParams.gravity = Gravity.LEFT;
holder.txtInfo.setLayoutParams(layoutParams);
}
}
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;
}
}
提前致谢
的K -
编辑:
主要问题是如何从已创建的列表视图中获取ID,这在Acepted答案中清楚地显示。
然而不是
chatMessages.get(i).id == message.id
我必须使用
chatMessages.get(i).getId() == message.getId()
但这是一个简单的解决方案,并且确实按预期工作
答案 0 :(得分:0)
您只能更新一行(更快,更多代码)或使用notifyDataSetChanged()
更新所有可见行(更慢,代码更少)。
ChatMessage message = ...; // updated message
adapter.update(message);
// update only one row
int start = messagesContainer.getFirstVisiblePosition();
for (int i = start, j = messagesContainer.getLastVisiblePosition(); i <= j; i++) {
if (message.id == adapter.getItem(i).id){
View view = messagesContainer.getChildAt(i-start);
adapter.getView(i, view, messagesContainer);
break;
}
}
// end of update only one row
// adapter.notifyDataSetChanged() // to update all visible rows
adapter.update()
的位置:
public void update(ChatMessage message) {
for (int i = 0; i < chatMessages.size(); i++) {
if (chatMessages.get(i).id == message.id) {
chatMessages.set(i, message);
break;
}
}
}
原始回答
当您更改chatMessages
列表时,您应该调用notifyDataSetChanged()
的{{1}}方法:
BaseAdapter