6

I am trying to build a simple chat application. With chat conversation screen I'm using ListView with ArrayAdapter to store and show the message but when I receive or send new message, all of recent message is change to.

This is my adapter code:

public class MessageAdapter extends ArrayAdapter<Message> {
    private Context context;
    private ArrayList<Message> messages;
    private DatabaseHelper databaseHelper;
    private Message message;

    @Override
    public void add(Message object) {
        messages.add(object);
        super.add(object);
    }

    public MessageAdapter(Context context, int textViewResouceId, ArrayList<Message> messages) {
        super(context, textViewResouceId);
        this.context = context;
        this.messages = messages;
        databaseHelper = DatabaseHelper.getInstance(context);
    }

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

    public Message getItem(int index) {
        return messages.get(index);
    }

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

    @Override
    public int getPosition(Message item) {
        return super.getPosition(item);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        MessageViewHolder messageViewHolder;

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.chat_item, parent, false);
            messageViewHolder = new MessageViewHolder();
            messageViewHolder.tv_userName = (TextView) convertView.findViewById(R.id.tv_chatName);
            messageViewHolder.tv_message = (TextView) convertView.findViewById(R.id.tv_messageContent);
            convertView.setTag(messageViewHolder);
        } else {
            messageViewHolder = (MessageViewHolder) convertView.getTag();
        }
        message = messages.get(position);
        String username = databaseHelper.getUserByUserId(message.getUserId()).getUserName();
        if (message.getUserId() == AppConfig.USER_ID) {
            messageViewHolder.tv_message.setTextColor(Color.parseColor("#0066ff"));
            messageViewHolder.tv_userName.setTextColor(Color.parseColor("#0066ff"));
        } else {
            messageViewHolder.tv_message.setTextColor(Color.parseColor("#000000"));
            messageViewHolder.tv_userName.setTextColor(Color.parseColor("#000000"));
        }
        messageViewHolder.tv_userName.setText(username);
        messageViewHolder.tv_message.setText(message.getMessage());

        return convertView;
    }

    static class MessageViewHolder {
        TextView tv_message;
        TextView tv_userName;
    }


}

This is my ListView Layout code:

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </android.support.design.widget.AppBarLayout>

        <ScrollView
            android:id="@+id/scroll_chat"
            android:layout_width="match_parent"
            android:layout_height="380dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <ListView
                    android:id="@+id/listMessage"
                    android:layout_width="match_parent"
                    android:layout_height="380dp"
                    android:background="@null"
                    android:divider="@null"
                    android:stackFromBottom="true"
                    android:drawSelectorOnTop="false"
                    android:transcriptMode="alwaysScroll" />
            </LinearLayout>


        </ScrollView>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:weightSum="1">

            <EditText
                android:id="@+id/txt_chat"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_weight="0.92" />

            <Button
                android:id="@+id/btn_send"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginLeft="30dp"
                android:text="@string/btn_send" />
        </LinearLayout>
    </LinearLayout>

And this is error when I send two message (the same error happen when I receive a message)

First Message

Second Message

I think the problem is the way set the data to View but I cannot solve it. Could anyone help me solve this issue.

This is chat screen when I close and open the activity again: It showed correct message.

enter image description here

This is Chatactivity code:

public class ChatActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btn_send;
    private static EditText txt_chat;
    private String registId;
    private Bundle bundle;
    private String chatTitle;
    private MessageSender mgsSender;
    private int userId;
    private DatabaseHelper databaseHelper;
    private TimeUtil timeUtil;
    private MessageAdapter messageAdapter;
    private ListView lv_message;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }
        btn_send = (Button) findViewById(R.id.btn_send);
        txt_chat = (EditText) findViewById(R.id.txt_chat);
        lv_message = (ListView) findViewById(R.id.listMessage);
//        lv_message.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        timeUtil = new TimeUtil();
        databaseHelper = DatabaseHelper.getInstance(getApplicationContext());
        btn_send.setOnClickListener(this);
        bundle = getIntent().getExtras();
        chatTitle = bundle.getString("titleName");
        if (getIntent().getBundleExtra("INFO") != null) {
            chatTitle = getIntent().getBundleExtra("INFO").getString("name");
            this.setTitle(chatTitle);
        } else {
            this.setTitle(chatTitle);
        }
        registId = bundle.getString("regId");
        userId = databaseHelper.getUser(chatTitle).getUserId();
        List<Message> messages = databaseHelper.getMessges(AppConfig.USER_ID, databaseHelper.getUser(chatTitle).getUserId());
        messageAdapter = new MessageAdapter(getApplicationContext(), R.layout.chat_item, (ArrayList<Message>) messages);
        LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg"));
        if (messages.size() > 0) lv_message.setAdapter(messageAdapter);
    }

    private BroadcastReceiver onNotice = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String message = intent.getStringExtra("message");
            try {
                Message messageObj = Message.getInstance();
                messageObj.setMessage(message);
                messageObj.setUserId(userId);
                messageObj.setSender_id(AppConfig.USER_ID);
                messageObj.setExpiresTime(timeUtil.formatDateTime(timeUtil.getCurrentTime()));
                messageAdapter.add(messageObj);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            messageAdapter.notifyDataSetChanged();
        }
    };


    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }


    @Override
    protected void onDestroy() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
        super.onDestroy();
    }


    private static MessageSenderContent createMegContent(String regId, String title) {
        String message = txt_chat.getText().toString();
        MessageSenderContent mgsContent = new MessageSenderContent();
        mgsContent.addRegId(regId);
        mgsContent.createData(title, message);
        return mgsContent;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_send:
                String message = txt_chat.getText().toString();
                databaseHelper = DatabaseHelper.getInstance(getApplicationContext());
                mgsSender = new MessageSender();
                new AsyncTask<Void, Void, Void>() {
                    @Override
                    protected Void doInBackground(Void... params) {
                        MessageSenderContent mgsContent = createMegContent(registId, AppConfig.USER_NAME);
                        mgsSender.sendPost(mgsContent);
                        return null;
                    }
                }.execute();
                databaseHelper.addMessage(message, timeUtil.getCurrentTime(), userId, AppConfig.USER_ID);
                txt_chat.setText("");
                try {
                    Message messageObj = Message.getInstance();
                    messageObj.setMessage(message);
                    messageObj.setUserId(AppConfig.USER_ID);
                    messageObj.setSender_id(userId);
                    messageObj.setExpiresTime(timeUtil.formatDateTime(timeUtil.getCurrentTime()));
                    messageAdapter.add(messageObj);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                messageAdapter.notifyDataSetChanged();
                break;
        }
    }

}
12
  • when you add a new item to the array you need to notify the adapter eg (adapter.notifyDataSetChanged();) -- try that and report back Commented Feb 22, 2016 at 3:22
  • does your messages array have correct data? Commented Feb 22, 2016 at 3:23
  • @Tasos I used adapter.notifyDataSetChanged() already and it work OK. The data was saved to database is correct, it just get error about display recent message Commented Feb 22, 2016 at 3:30
  • @PhanVănLinh Yes, it is. When I close and open the activity again, it show message correct, it just get error when I send or receive new message :( Commented Feb 22, 2016 at 3:32
  • did you solve your problem?. Can you post the screen where the message show correct Commented Feb 22, 2016 at 3:36

1 Answer 1

2

In your ChatActivity. In onClickEvent
Try to change

Message messageObj = Message.getInstance();

to

Message messageObj = new Message();

You can read more about Singleton Pattern in here

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, it work successful. Could you explain the reason for me. I am still confuse about it. :)
Sorry, I cannot explain well about it because I know a little. It is Singleton Design Pattern. You should research about it then you will understand your problem ;)
Got it. Thank you :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.