I'm trying to deal with nine patches and word wrapping inside a text view. The problem is that TextView doesn't resize its width to wrapped text, so the chat bubbles left a huge gap which I cannot reduce.
chat bubbles with gaps
Investigation of ViewHierarchy shows that these gaps are inside the TextView, view hierarchy of chat layout. so it's not related to the nine-patch.
May be somebody faced a similar issue...
<LinearLayout
android:id="@+id/messages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/senderName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:gravity="bottom|start"
android:maxLines="1"
android:layout_marginTop="5dp"
android:layout_marginStart="18dp"
android:layout_marginLeft="18dp"
android:textColor="@color/talkatone_gray"
android:textSize="@dimen/chat_item_meta_info_text_size"
android:visibility="gone"/>
<TextView
android:id="@+id/message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginBottom="@dimen/chat_bubble_margin_top"
android:background="@android:color/transparent"
android:lineSpacingExtra="4sp"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_vertical"
android:text="@string/form_chat_failed_to_open"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/chat_text"
android:textSize="@dimen/chat_text_message_size"/>
<FrameLayout
android:id="@+id/attachment_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/chat_bubble_margin_top"
android:orientation="vertical">
<ImageButton
android:id="@+id/video_play_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:background="@android:color/transparent"
android:contentDescription="@null"
android:src="@drawable/play_gif"/>
</FrameLayout>
in your case the main problem is that you use it in adapter with viewholder pattern implementation.
So there is two issues you need to solve:
For reset TextView width add to your adapter getView() method, when you reuse your holder, next:
ViewGroup.LayoutParams paramsReset = holder.messageText.getLayoutParams();
paramsReset.width = ViewGroup.LayoutParams.WRAP_CONTENT;
holder.messageText.setLayoutParams(paramsReset);
For second issue you need to create custom view, extended from TextView and override onDraw() method:
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if(getLineCount() > 1)
{
float longestLineWidth = -1;
for (int lineIndex = 0; lineIndex < getLineCount(); lineIndex++)
{
int lineStartIndex = getLayout().getLineStart(lineIndex);
int lineEndIndex = getLayout().getLineEnd(lineIndex);
String currentTextLine = getText().toString().substring(lineStartIndex, lineEndIndex);
// Added "_____" for your paddings.
float currentLineWidth = getPaint().measureText(currentTextLine + "_____");
if (longestLineWidth < currentLineWidth)
{
longestLineWidth = currentLineWidth;
}
}
ViewGroup.LayoutParams paramsNew = getLayoutParams();
paramsNew.width = (int) longestLineWidth;
setLayoutParams(paramsNew);
}
}
I override onDraw() also because of needed for use it in ListView, looks like you'll need to find other callback, that calls when holder has appeared in view.
It works, but not efficient, and have some other issues, please use it as first step.