Android TextView 折叠高度

在Android开发中,TextView是一种常用的UI控件,用于显示文本内容。有时候,我们需要在TextView中显示大段的文本内容,但是又希望在空间有限的情况下只显示部分文本,其余文本可以通过折叠的方式展示。本文将介绍如何实现TextView的折叠高度功能,并提供相关的代码示例。

实现思路

要实现TextView的折叠高度功能,我们可以通过设置TextView的最大行数来实现。当文本内容超过指定的行数时,我们可以将多余的文本隐藏起来,并通过添加一个展开/折叠按钮来控制文本的显示与隐藏。

具体的实现思路如下:

  1. 获取TextView的实际高度和行高。
  2. 根据所需显示的行数计算TextView的折叠高度。
  3. 将TextView的行数设置为所需显示的行数。
  4. 如果文本的行数超过所需显示的行数,则添加一个展开/折叠按钮。
  5. 点击展开/折叠按钮时,根据当前TextView的状态来切换文本的显示与隐藏。

下面是一个实现TextView折叠高度功能的代码示例:

public class CollapsibleTextView extends AppCompatTextView {
    private static final int DEFAULT_COLLAPSED_LINES = 3;

    private int collapsedLines;
    private boolean isCollapsed;

    public CollapsibleTextView(Context context) {
        this(context, null);
    }

    public CollapsibleTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CollapsibleTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        
        // 从XML属性中获取折叠行数
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CollapsibleTextView);
        collapsedLines = a.getInt(R.styleable.CollapsibleTextView_collapsedLines, DEFAULT_COLLAPSED_LINES);
        a.recycle();
        
        init();
    }

    private void init() {
        // 获取TextView的行高
        Paint.FontMetrics fm = getPaint().getFontMetrics();
        int lineHeight = (int) Math.ceil(fm.bottom - fm.top);

        // 设置TextView的最大行数
        setMaxLines(collapsedLines);

        // 计算TextView的折叠高度
        int collapsedHeight = lineHeight * collapsedLines;
        setHeight(collapsedHeight);
        
        // 添加展开/折叠按钮
        if (getLineCount() > collapsedLines) {
            setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_expand, 0);
            setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    toggle();
                }
            });
        }
    }

    private void toggle() {
        if (isCollapsed) {
            // 展开TextView
            setMaxLines(Integer.MAX_VALUE);
            setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_collapse, 0);
        } else {
            // 折叠TextView
            setMaxLines(collapsedLines);
            setHeight(collapsedHeight);
            setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_expand, 0);
        }
        isCollapsed = !isCollapsed;
    }
}

上述代码中,我们创建了一个名为CollapsibleTextView的自定义控件,继承自AppCompatTextView。在构造函数中,我们获取了XML属性中设置的折叠行数,并进行了相应的初始化操作。其中,R.styleable.CollapsibleTextView_collapsedLines是在XML中定义的自定义属性,用于指定折叠行数的默认值。

init()方法中,我们获取了TextView的行高,并根据折叠行数计算了TextView的折叠高度。然后,我们设置了TextView的最大行数和高度,并根据需要添加了展开/折叠按钮。

toggle()方法中,我们通过切换TextView的最大行数和高度以及展开/折叠按钮的图标来实现文本的显示与隐藏。

序列图

下面是一个使用CollapsibleTextView控件的序列图,展示了用户点击展开/折叠按钮时的交互过程:

sequenceDiagram
    participant User
    participant CollapsibleTextView
    participant OnClickListener

    User->>CollapsibleTextView: 点击展开/折