Android 可折叠TextView:释放文本的无限可能
2023-09-07 21:05:17
Android 可折叠TextView:让你的文本随心所欲
技术在不断进步,而 Android 也不例外。作为移动应用开发领域的主流平台,Android 始终致力于为开发者提供强大的工具和功能,让其打造出创新且用户友好的应用。其中,TextView 组件便是 Android UI 中不可或缺的一部分,它负责显示文本内容。然而,对于超出行数限制的文本,传统的 TextView 只能通过截断或滚动的方式来处理,这限制了其在某些场景下的使用。
有鉴于此,本文将重点介绍一款功能强大的 Android 控件——可折叠TextView。它允许开发者在文本超过指定行数后,显示一个省略号和一个“全文”链接,从而让用户可以轻松展开或收起文本内容。这种特性在微博、B站等应用中非常常见,不仅提升了用户体验,还节省了宝贵的屏幕空间。
实现原理
为了实现可折叠TextView,我们可以继承 AppCompatTextView 并重写其 onMeasure() 和 onDraw() 方法。在 onMeasure() 方法中,我们需要测量要拼接的内容(通常是“...”和“全文”)的宽度。需要注意的是,这里的测量会存在一个小问题,提示内容会紧跟在原始文本之后,而不是出现在 TextView 的边界上。我们可以使用 Canvas.clipRect() 方法来解决这个问题。
在 onDraw() 方法中,我们可以绘制原始文本内容。如果文本超过了指定行数,则在最后一行末尾绘制省略号,并在其后面绘制“全文”链接。当用户点击“全文”链接时,我们可以通过设置 TextView 的 maxLines 属性为 Integer.MAX_VALUE 来展开文本内容,此时省略号和“全文”链接将消失。收起文本内容的操作与之类似,只需将 maxLines 属性重置为指定的行数即可。
实际应用
可折叠TextView 在实际应用中具有广泛的用途,以下列举几个示例:
- 微博评论: 微博的评论区中,经常会出现过长的评论。使用可折叠TextView,用户可以快速预览评论的内容,点击“全文”链接后再展开阅读,避免了长文带来的视觉疲劳。
- 新闻摘要: 新闻应用中,通常会显示新闻摘要。对于较长的新闻摘要,我们可以使用可折叠TextView 来控制摘要的显示长度,让用户先了解新闻的大致内容,再决定是否展开阅读全文。
- 商品 电商应用中,商品往往包含大量的信息。我们可以使用可折叠TextView 来控制商品的显示长度,避免给用户造成信息过载的感觉。
代码示例
public class FoldableTextView extends AppCompatTextView {
private static final int DEFAULT_MAX_LINES = 3;
private int maxLines = DEFAULT_MAX_LINES;
private String fullText;
private boolean isFolded = true;
public FoldableTextView(Context context) {
super(context);
init();
}
public FoldableTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FoldableTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
toggleFold();
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 测量要拼接的内容的宽度
Paint paint = getPaint();
String ellipsis = "...";
String fullText = getText().toString();
float ellipsisWidth = paint.measureText(ellipsis);
float fullTextWidth = paint.measureText(fullText);
// 计算最大行数
int maxLines = this.maxLines;
int lineHeight = getLineHeight();
int height = getMeasuredHeight();
if (height > maxLines * lineHeight) {
maxLines--;
}
// 如果文本超过了最大行数,则显示省略号和"全文"链接
if (fullTextWidth > getMeasuredWidth()) {
this.fullText = fullText;
setMaxLines(maxLines);
append(ellipsis + "全文");
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制省略号和"全文"链接
if (isFolded) {
Paint paint = getPaint();
String ellipsis = "...";
String fullText = getText().toString();
float ellipsisWidth = paint.measureText(ellipsis);
float fullTextWidth = paint.measureText(fullText);
if (fullTextWidth > getMeasuredWidth()) {
canvas.save();
canvas.clipRect(getMeasuredWidth() - ellipsisWidth, 0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawText(ellipsis, getMeasuredWidth() - ellipsisWidth, getLineBounds(getLineCount() - 1, null)[1], paint);
canvas.restore();
}
}
}
public void toggleFold() {
isFolded = !isFolded;
if (isFolded) {
setMaxLines(maxLines);
append("全文");
} else {
setMaxLines(Integer.MAX_VALUE);
setText(fullText);
}
}
public void setMaxLines(int maxLines) {
this.maxLines = maxLines;
super.setMaxLines(maxLines);
}
}
结语
可折叠TextView 是一种非常有用的 Android 控件,它可以帮助开发者解决文本内容超出行数限制的问题,同时提升用户体验和节省屏幕空间。通过本文提供的实现原理和代码示例,开发者可以轻松地将可折叠TextView集成到自己的应用中。随着 Android 技术的不断发展,相信可折叠TextView 将在更多应用场景中发挥其作用,为用户带来更加便捷和个性化的交互体验。