Android阵列适配器项目更新

Android阵列适配器项目更新,android,listview,arraylist,Android,Listview,Arraylist,我正试图基于以下文章实现一个简单的聊天应用程序: 我已经设法让我的聊天正常进行了 这是我的一系列事件 将新消息发送到MySql Db并返回一个JSON,状态为消息已传递,然后我将一条GCM消息发送到接收设备,该接收设备正在为最广泛的接收器列表,并启动一个函数以添加新消息。所有这些都很好,一旦mesage从服务器上下载,我就会向发送者发送一个GCM,通知消息已被读取。这就是我被困的地方:( 如何更新已填充的listview以显示更改 例如: // Do a JSON call for the c

我正试图基于以下文章实现一个简单的聊天应用程序:

我已经设法让我的聊天正常进行了

这是我的一系列事件

将新消息发送到MySql Db并返回一个JSON,状态为消息已传递,然后我将一条GCM消息发送到接收设备,该接收设备正在为最广泛的接收器列表,并启动一个函数以添加新消息。所有这些都很好,一旦mesage从服务器上下载,我就会向发送者发送一个GCM,通知消息已被读取。这就是我被困的地方:(

如何更新已填充的listview以显示更改

例如:

// 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();
} 
请参阅下面的基本代码

聊天活动

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);
                }
    }
}
聊天适配器

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;
    }
}
我不得不使用

chatMessages.get(i).getId() == message.getId()

但这是一个简单的解决方案,并且确实可以按预期工作

您可以只更新一行(更快,更多代码),或者使用
notifyDataSetChanged()
(更慢,更少代码)更新所有可见行

原始答案

更改
chatMessages
列表时,应调用
notifyDataSetChanged()
方法
BaseAdapter

public void add(ChatMessage message) {
    chatMessages.add(message);
    notifyDataSetChanged();
}

public void add(List<ChatMessage> messages) {
    chatMessages.addAll(messages);
    notifyDataSetChanged();
}
public void添加(ChatMessage){
添加(消息);
notifyDataSetChanged();
}
公共无效添加(列出消息){
chatMessages.addAll(消息);
notifyDataSetChanged();
}

notifyDataSetChanged();在添加新消息时在ChatActivity中被调用。(displayMessage),这100%起作用,我的问题是如何更改已添加和显示的消息?@Kenny所以您需要为已在适配器中的消息更新
ListView
项?这就是我试图实现的目标向ChatMessage添加新字段“isRead”并在收到通知时提及对手已阅读,通过其id获取ChatMessage(更新isRead=true)并通知DatasetChanged。@Khawar请您发布一个示例,我不确定如何通过其IDPossible副本获取消息
chatMessages.get(i).getId() == message.getId()
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
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;
      }   
    }
}
public void add(ChatMessage message) {
    chatMessages.add(message);
    notifyDataSetChanged();
}

public void add(List<ChatMessage> messages) {
    chatMessages.addAll(messages);
    notifyDataSetChanged();
}