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>
使用9个补丁图像作为布局的背景,这样您就可以创建位图图像,该位图图像会自动调整大小以容纳视图的内容。
Unfortunately, your question also includes your answer:
TextView doesn't resize its width to wrapped text
When you use wrap_content
and allow multiple lines, the system will first grow the width of the TextView
as wide as it can and only then start adding linebreaks. It never does a pass at the end to reclaim available width.
Of course, as with all things, you can solve this problem by writing your own custom TextView
class. Here's a link to another project that attempted to solve a similar problem; maybe it will help give you ideas.
Other question: Uniform text wrapping in TextView
Custom TextView lib: https://github.com/dziobas/UniformTextView
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.