title: Setting width of textview inside listview not working (custom ArrayAdapter)
body: <p>I am developing a messenger app (my "own" WhatsApp) on android, for which I am now trying to dynamically inflate the message history. I am using a custom ArrayAdapter for this. The messages should always only take up 5/6 of my screen width, so theres always a free place next to the message. My problem is, that it ignores the maxWidth I set and that I cannot set the width using <code>textView.setWidth()</code> neither using LayoutParams.</p>
  
  <p>When I just create one message, the TextView is respecting the maxWidth, but <code>getWidth(</code>) returns something higher (how is this possible?). When I create another message, the TextView expands to the width <code>getWidth()</code> returned before and the layout settings get resetted.</p>
  
  <p>Here are my files:</p>
  
  <p><strong>message_from.xml:</strong></p>
  
  <pre><code>    &lt;?xml version="1.0" encoding="utf-8"?&gt;
      &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/message_from"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:background="@drawable/message_from"
          android:gravity="start" &gt;
  
              &lt;TextView
                  android:id="@+id/messageText"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:maxWidth="400dp"
                  android:paddingStart="6dp"
                  android:paddingLeft="6dp"
                  android:paddingEnd="4dp"
                  android:paddingRight="4dp"
                  android:paddingTop="4dp"
                  android:paddingBottom="2dp"
                  android:textSize="16sp" /&gt;
  
               &lt;TextView
                   android:id="@+id/timeView"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:paddingBottom="4dp"
                   android:paddingStart="2dp"
                   android:paddingLeft="2dp"
                   android:paddingEnd="4dp"
                   android:paddingRight="4dp"
                   android:textColor="#707070"
                   android:textSize="12sp" /&gt;
  
  
  
      &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p><strong>activity_chat.xml</strong></p>
  
  <pre><code> &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical" android:layout_width="match_parent"
          android:layout_height="match_parent" &gt;
  
              &lt;ListView
                  android:id="@+id/messagesListView"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:divider="@null"
                  android:dividerHeight="0dp" /&gt;
      &lt;RelativeLayout/&gt;
  </code></pre>
  
  <p><strong>MessageListItem.java</strong></p>
  
  <pre><code>public class MessageListItem {
  public String text;
  public long time;
  public String timeFormatted;
  public boolean from;
  public int state;
  public Drawable stateImage;
  private int stateResourceId;
  
  final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());
  
      public MessageListItem() {
          super();
      }
  
      public MessageListItem(String text, long time, boolean from, int state, Context c) {
          super();
          this.text = text;
          this.time = time;
          this.from = from;
          this.state = state;
          timeFormatted = timeFormat.format(time);
  }
  }
  </code></pre>
  
  <p><strong>MessageAdapter.java</strong> (only important parts, click <a href="http://5.231.67.13/files/MessageAdapter.txt" rel="nofollow">here</a> for complete file)</p>
  
  <pre><code>    public class MessageAdapter extends ArrayAdapter&lt;MessageListItem&gt; {
  
          int resourceIdFrom = R.layout.message_from;
          Context context;
          MessageListItem[] data;
          static View row;
          static ListHolder holder;
  
          public MessageAdapter(Context context, int resourceId, MessageListItem[] data) {
              super(context, resourceId, data);
              this.context = context;
              this.data = data;
          }
  
          @Override
          public View getView(final int position, View convertView, final ViewGroup parent) {
              row = convertView;
              if (row == null) {
                  LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                  holder = new ListHolder();
                  if (data[position].from) {
                      row = (RelativeLayout) inflater.inflate(resourceIdFrom, parent, false);
                      holder.messageText = (TextView) row.findViewById(R.id.messageText);
                      holder.timeView = (TextView) row.findViewById(R.id.timeView);
                      MessageListItem message = data[position];
                      holder.messageText.setText(message.text);
                      holder.timeView.setText(message.timeFormatted);
  
                      ViewTreeObserver observer = row.getViewTreeObserver();
                      observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                          @SuppressLint("NewApi")
                          @SuppressWarnings("deprecation")
                          @Override
                          public void onGlobalLayout() {
                              positionViews();
                              if (android.os.Build.VERSION.SDK_INT &gt;= 16) {
                              row.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                              } else {
                                  row.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                              }
                          }
                      });
                  row.setTag(holder);
              }
               holder = (ListHolder) row.getTag();
              }
              return row;
          }
  
      static class ListHolder {
          ImageView messageState;
          TextView messageText;
          TextView timeView;
      }
  
      public void positionViews() {
          Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
          Point size = new Point();
          display.getSize(size);
          holder.messageText.setMaxWidth(size.x / 6 * 5); //doesn't work? 
          if (holder.messageText.getWidth() &gt; holder.messageText.getMaxWidth()) holder.messageText.setWidth(holder.messageText.getMaxWidth()); // doesn't work either
          holder.messageText.invalidate();
          System.out.println(holder.messageText.getWidth()); // always returns 464, no matter how big the TextView is
      }
  }
  </code></pre>
  
  <p>To use it:</p>
  
  <pre><code>MessageListItem[] testData = new MessageListItem[2];
  for (int i = 0; i&lt;=1; i++) testData[i] = new MessageListItem("I can dynamically create message bubbles!", System.currentTimeMillis(), true, 0, this);
  final MessageAdapter adapter = new MessageAdapter(this, R.layout.listview_item_row, testData);
  messageList.setAdapter(adapter);
  </code></pre>
  
  <p>Screenshot <a href="http://5.231.67.13/files/screenshot.png" rel="nofollow">here</a></p>
  
  <p>Thank you for any advice.</p>