android 将聊天气泡宽度调整为换行文本
android resize chat bubbles width to wrapped text
我正在尝试处理文本视图中的九个补丁和自动换行。问题是 TextView 不会将其宽度调整为换行文本,因此聊天气泡留下了一个我无法减少的巨大差距。
有空隙的聊天气泡
对 ViewHierarchy 的调查表明,这些间隙位于聊天布局的视图层次结构 TextView 内部。所以跟九段没有关系。
可能有人遇到过类似的问题...
<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 个补丁图像作为布局的背景,这样您就可以创建可自动调整大小以适应视图内容的位图图像。
很遗憾,您的问题还包括您的答案:
TextView doesn't resize its width to wrapped text
当您使用 wrap_content
并允许多行时,系统将首先尽可能地增加 TextView
的宽度,然后才开始添加换行符。它从不在最后通过传递以回收可用宽度。
当然,与所有事情一样,您可以通过编写自己的自定义来解决此问题TextView
class。这是另一个试图解决类似问题的项目的 link;也许它会帮助你出主意。
其他问题:Uniform text wrapping in TextView
自定义 TextView 库:https://github.com/dziobas/UniformTextView
在你的情况下,主要问题是你在适配器中使用它来实现 viewholder 模式。
所以您需要解决两个问题:
- 每次重新使用之前重置 TextView 的宽度。
- 在您的 TextView 度量中定义最长的行并设置适当的宽度。
要重置 TextView 宽度,请将其添加到您的适配器 getView() 方法中,当您重复使用您的 holder 时,下一步:
ViewGroup.LayoutParams paramsReset = holder.messageText.getLayoutParams();
paramsReset.width = ViewGroup.LayoutParams.WRAP_CONTENT;
holder.messageText.setLayoutParams(paramsReset);
对于第二期,您需要创建自定义视图,从 TextView 扩展并覆盖 onDraw() 方法:
@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);
}
}
我覆盖了 onDraw() 也是因为需要在 ListView 中使用它,看起来你需要找到其他回调,当 holder 出现在视图中时调用。
有效,但效率不高,还有一些其他问题,请作为第一步使用。
我正在尝试处理文本视图中的九个补丁和自动换行。问题是 TextView 不会将其宽度调整为换行文本,因此聊天气泡留下了一个我无法减少的巨大差距。
有空隙的聊天气泡
对 ViewHierarchy 的调查表明,这些间隙位于聊天布局的视图层次结构 TextView 内部。所以跟九段没有关系。
可能有人遇到过类似的问题...
<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 个补丁图像作为布局的背景,这样您就可以创建可自动调整大小以适应视图内容的位图图像。
很遗憾,您的问题还包括您的答案:
TextView doesn't resize its width to wrapped text
当您使用 wrap_content
并允许多行时,系统将首先尽可能地增加 TextView
的宽度,然后才开始添加换行符。它从不在最后通过传递以回收可用宽度。
当然,与所有事情一样,您可以通过编写自己的自定义来解决此问题TextView
class。这是另一个试图解决类似问题的项目的 link;也许它会帮助你出主意。
其他问题:Uniform text wrapping in TextView
自定义 TextView 库:https://github.com/dziobas/UniformTextView
在你的情况下,主要问题是你在适配器中使用它来实现 viewholder 模式。
所以您需要解决两个问题:
- 每次重新使用之前重置 TextView 的宽度。
- 在您的 TextView 度量中定义最长的行并设置适当的宽度。
要重置 TextView 宽度,请将其添加到您的适配器 getView() 方法中,当您重复使用您的 holder 时,下一步:
ViewGroup.LayoutParams paramsReset = holder.messageText.getLayoutParams();
paramsReset.width = ViewGroup.LayoutParams.WRAP_CONTENT;
holder.messageText.setLayoutParams(paramsReset);
对于第二期,您需要创建自定义视图,从 TextView 扩展并覆盖 onDraw() 方法:
@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);
}
}
我覆盖了 onDraw() 也是因为需要在 ListView 中使用它,看起来你需要找到其他回调,当 holder 出现在视图中时调用。
有效,但效率不高,还有一些其他问题,请作为第一步使用。