2

I have a chat functionality in my app and I want to group sequential messages from the same user, something similar to that picture bellow:

Mock-up

So, I have my message_row.xml with one TextView to display the content of one message. My Message model has an ArrayList with all the sequential messages from the same user.

My CustomMessageAdapter.java looks like that:

if (inflater == null) {
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

// [...]

if (getItemViewType(position) == MINE) {
    convertView = inflater.inflate(R.layout.my_message_row, null);
} else {
    convertView = inflater.inflate(R.layout.message_row, null);
}

// [...]

TextView senderName = (TextView) convertView.findViewById(R.id.senderName);
TextView content = (TextView) convertView.findViewById(R.id.content);

senderName.setText(message.getSenderName());

//I want to do something like this:

for (int i = 0; i < message.getMessages().size(); i++) {
    // display a different TextView for each different message...
}

// [...]

return convertView;

What I cannot do is display a new TextView for each different messages in messages arraylist.

Otacilio Oliveira
  • 686
  • 1
  • 5
  • 15

4 Answers4

2

As inflating view classes is expensive and updating them can also be expensive it would be wise to take a simpler approach to this problem. I would suggest simply concatenating the strings with newlines delimiters and apply the entirety to the message.

Further Thoughts

Should you need complex control over the display of the text, consider using Spannable to format your text inside a single TextView.

http://developer.android.com/reference/android/text/Spannable.html

As demonstrated here: Is there any example about Spanned and Spannable text

spanbuffer = new TextView(context);
spanbuffer.setText(newText, TextView.BufferType.SPANNABLE);
Spannable s = (Spannable) spanbuffer.getText();
s.setSpan(new ForegroundColorSpan(Color.RED), 0, newText.length() - 1, 0);
this.append(s);

You can control several text attributes in this manner.

Community
  • 1
  • 1
ian.shaun.thomas
  • 3,468
  • 25
  • 40
  • Spannable looks like a good alternative, but I didn't figure out how to apply my `message_background.xml` as its background or even draw it (this xml file is basically a rectangle shape with radius borders. – Otacilio Oliveira Jul 31 '15 at 04:29
  • Spannable has a background color option, you would use that instead of a drawable. If you need custom drawables wrapping around text then yes you'll either have to do inflate lots of TextView instances or create your own TextView implementation for this which would be very difficult. I *believe* those are your only options in regards to keeping it pure android and not using something like a WebView. – ian.shaun.thomas Jul 31 '15 at 14:10
0

I would suggest in your message_row.xml instead of inflating TextView inflate linear layout and in that linear layout add TextViews programmatically for each iteration in

for (int i = 0; i < message.getMessages().size(); i++) {
    // display a different TextView for each different message...
}

But, since inflating is expensive i would suggest to split your messages with new row and add them all in one TextView.

Viktor Petrovski
  • 796
  • 5
  • 14
0

in your array create a id for two persons of conversation when you paint in the adapter indentify waths id is and paint the texview corresponding something like this:

if (iduser.equals("1")){ textviewUser.setText("some text");}else{texviewOther.setText("sometext")} 
0

add dynamic textview to your row,

private void createTextView(LayoutInflater inflater, LinearLayout llTv) {
    llTv.removeAllViews();
    int i = 0;
    while (i < mMessages.size()) {
        View llTv= inflater.inflate(R.layout.textTtem, llTv, false);
        TextView textView = (TextView) llTv.findViewById(R.id.tv_message);
        textView.setText(mMessage.get(i).getMesage());
        textView.setOnClickListener(this);
        llTv.addView(textView);
        i++;
    }
}

your textitem should look like this,

<?xml version="1.0" encoding="utf-8"?>
   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:animateLayoutChanges="true"
      android:orientation="vertical">
       <TextView
          android:id="@+id/tv_message"
          android:layout_width="match_parent"
          android:padding="..."
          android:layout_margin="..."
          android:layout_height="wrap_content"
          android:textSize="14sp"/>
 </LinearLayout> 

you can send inflater like this:

mInflater = LayoutInflater.from(mContext);
Aditya Chauhan
  • 271
  • 3
  • 13