Android可收缩/扩展的TextView(CollapsibleTextView)

前言:在某些应用中,总会遇到一些类似于公告、简介、说明等长文本的TextView,但是为了排版美观等因素,我们通常是要隐藏后半部的文本,而是显示三四行的开始部分(摘要),然后在尾部会提供用户一个扩展/收缩的按钮,使得文本框可以在需要的时候扩展开来查看全文。

前段时间我们的项目也需要这样的效果,就借鉴了一下网上的文章原理并做了算法优化和逻辑修改,自己实现了一个复用性还算可以的可收缩/扩展的TextView:CollapsibleTextView

今天就贴出来,如果哪位小伙伴需要可以copy一下在项目中使用。

支持功能

1、文本可收起显示特定行数,展开显示全部文本。

2、在文本末尾的 收起/展开 按钮可用文本显示也可用图片icon显示。

3、在文本末尾的 收起/展开 按钮支持在最后一行末尾显示,也支持另起一行在末尾显示。

4、通过修改类代码逻辑可以快速方便定制自己的产品效果。

实现原理

1、收起时使用android:lines来设置TextView的行数,显示特定的行数;点击按钮展开之后,解除行数限制显示全部内容。

2、文本最后的 “...” 省略符号通过在显示文本最后进行手动拼接的形式实现。

3、要记得设置android:layout_height="wrap_content",不然固定了高度,就没法实现了。

4、后缀的按钮是否是文案或者图片通过配置可以控制,生成的方式是最后在onDraw方法给绘制出来。

代码实现

文本展开收起组件的接口:

/**
 * 文本展开收起组件的接口
 * @author zhangmeng25
 */
public interface ICollapsibleTextViewParent {
    void setViewHeight(int height);
}

文案展开收起组件容器:

/**
 * 文案展开收起组件
 * @author zhangmeng25
 */
public class CollapsibleTextViewParentFrameLayout extends FrameLayout
        implements ICollapsibleTextViewParent {

    public CollapsibleTextViewParentFrameLayout(@NonNull Context context) {
        super(context);
    }

    public CollapsibleTextViewParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CollapsibleTextViewParentFrameLayout(@NonNull Context context,
                                                @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setViewHeight(int height) {
        getLayoutParams().height = height + getPaddingTop() + getPaddingBottom();
        requestLayout();
    }
}

文本展开收起组件:

/**
 * 文本展开收起组件
 * @author zhangmeng25
 */
public class CollapsibleTextView extends android.support.v7.widget.AppCompatTextView {
    /** 动画执行的时间 */
    public static final long ANIM_DURATION = 200L;
    /** 文本收起后缀 */
    public static final String SUFFIX_PREFIX = "...";
    /** 文本后缀的文案颜色 */
    private int mSuffixColor = 0xff0000ff;
    /** 文本收起的行数 */
    private int mCollapsedLines = 1;
    /** 文本收起的最小行数 */
    private int mMinCollapseLines;
    /** 当前控件的文本 */
    private String mText;
    /** 是否需要初始化layout */
    private boolean mShouldInitLayout = true;
    /** 当前控件是否是展开态 */
    private boolean mExpanded = false;
    /** 控件的后缀展开文案 */
    private String mCollapsedText = " Show All";
    /** 控件的后缀收起文案 */
    private String mExpandedText = " Hide ";
    private String mExpandedChText = " 展开 ";
    /** 用于换行的后知文案 */
    private String mCollapsedTag = "\n     ";
    /** 行数变化的动画 */
    private ValueAnimator mChangeHeightAnimator;
    /** 接口 */
    private ICollapsibleTextViewParent mParent;
    /** 收起时的高度 */
    private int mCollapsedHeight;
    /** 后缀文案的尺寸 */
    private float mRelativeSize;
    /** 后缀文案是否加粗 */
    private boolean isSuffixBold;
    /** 是否应该显示后缀 */
    private boolean showHideSuffix;
    /** 是否需要执行动画 */
    private boolean doAnimator;
    /** 控件的收起显示icon */
    private Drawable mTagDrawableClose;
    private Bitmap mTagDrawableCloseBitmap;
    /** 控件的展开显示icon */
    private Drawable mTagDrawableOpen;
    private Bitmap mTagDrawableOpenBitmap;
    /** 文本展开收起组件点击事件监听 */
    private OnCollapsibleClickListener mListener;

    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);
        TypedArray attributes = context.getTheme()
                .obtainStyledAttributes(attrs, R.styleable.CollapsibleTextView, defStyleAttr, 0);

        mSuffixColor = attributes.getColor(R.styleable.CollapsibleTextView_suffixColor, 0xff0000ff);
        mCollapsedLines = attributes.getInt(R.styleable.CollapsibleTextView_collapsedLines, 2);
        mCollapsedText = attributes.getString(R.styleable.CollapsibleTextView_collapsedText);
        mMinCollapseLines = attributes.getInteger(R.styleable.CollapsibleTextView_min_collapse_lines, 2);
        mRelativeSize = attributes.getFraction(R.styleable.CollapsibleTextView_suffixRelativeSize, 1, 1, 1.f);
        isSuffixBold = attributes.getBoolean(R.styleable.CollapsibleTextView_suffixBoldText, false);
        showHideSuffix = attributes.getBoolean(R.styleable.CollapsibleTextView_showHideSuffix, true);
        doAnimator = attributes.getBoolean(R.styleable.CollapsibleTextView_doAnimator, true);
        mTagDrawableClose = attributes.getDrawable(R.styleable.CollapsibleTextView_suffixDrawableClose);
        mTagDrawableOpen = attributes.getDrawable(R.styleable.CollapsibleTextView_suffixDrawableOpen);

        initTagBitmap(); // 初始化时将标志图片给完成加载构建

        if (TextUtils.isEmpty(mCollapsedText)) {
            mCollapsedText = " Show All";
        }

        mExpandedText = attributes.getString(R.styleable.CollapsibleTextView_expandedText);
        if (TextUtils.isEmpty(mExpandedText)) {
            mExpandedText = " Hide";
        }

        this.mText = getText() == null ? "" : getText().toString();

        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                CollapsibleTextView.this.pendingFullString(!isExpanded(),
                        Collapsibl
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值