一个简单的可伸缩TextView

本文介绍了如何在Android中创建一个可伸缩的TextView,详细阐述了实现代码、布局配置和使用方法,提供了简单的实现思路,并指出代码还有优化空间,界面样式和文本内容可根据实际项目需求定制。

要实现的效果如图:

在这里插入图片描述在这里插入图片描述

实现代码

public class ExpandTextView extends RelativeLayout {
    private TextView mText;
    private TextView mExpandText;
    private int mTextColor = 0xff828282;
    private int mTextLine = 1;
    private int mStart;
    private int mEnd;
    private boolean isFirst = true;
    private boolean isExpand = false;

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

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

    public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        mText = new TextView(context, attrs);
        mText.setTextColor(mTextColor);
        mText.setEllipsize(TextUtils.TruncateAt.END);
        mText.setMaxLines(mTextLine);
        addView(mText, params);
        mExpandText = new TextView(context);
        mExpandText.setTextColor(mTextColor);
        addView(mExpandText, params);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final ViewGroup.LayoutParams params = getLayoutParams();
        if (isFirst){
            isFirst = false;
            mText.post(new Runnable() {
                @Override
                public void run() {
                    mStart = mText.getLineHeight() * mText.getLineCount();
                    params.height = mStart;
                    setLayoutParams(params);
                }
            });
            mExpandText.post(new Runnable() {
                @Override
                public void run() {
                    mEnd = mExpandText.getLineHeight() * (mExpandText.getLineCount()+1);
                }
            });
        }
    }

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
        super.setLayoutParams(params);
    }

    public void setText(String text){
        isFirst = true;
        mText.setText(text);
        mExpandText.setText(text);
        requestLayout();
    }

    public void setTextColor(int color){
        mText.setTextColor(color);
    }

    public void setTextSize(int size) {
        isFirst = true;
        mText.setTextSize(size);
        mExpandText.setTextSize(size);
        requestLayout();
    }

    public void setTextMaxLine(int num) {
        mTextLine = num;
        mText.setMaxLines(num);
    }

    public void setGravity(int gravity) {
        mText.setGravity(gravity);
        mExpandText.setGravity(gravity);
    }

    public void setEllipsize(TextUtils.TruncateAt ell) {
        mText.setEllipsize(ell);
    }

    public void setTextLineSpacingExtra(float spac) {
        mText.setLineSpacing(spac, 1.0f);
        mExpandText.setLineSpacing(spac, 1.0f);
    }

    public TextView text() {
        return mText;
    }

    public TextView expandText() {
        return mExpandText;
    }

    public int line() {
        return mTextLine;
    }

    public boolean isExpand() {
        return isExpand;
    }

    /*
     * 展开文本
     */
    public void expand(){
        if (!isExpand){
            isExpand = true;
            mText.setEllipsize(null);
            mText.setTextColor(mTextColor);
            mExpandText.setTextColor(mTextColor);
            Animation animation = new Animation() {
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) {
                    ViewGroup.LayoutParams params = ExpandTextView.this.getLayoutParams();
                    params.height = mStart + (int) ((mEnd - mStart) * interpolatedTime);
                    setLayoutParams(params);
                }
            };
            animation.setDuration(500);
            startAnimation(animation);
        }
    }

    /*
     * 收起文本
     */
    public void retract(){
        if (isExpand){
            isExpand = false;
            mText.setEllipsize(TextUtils.TruncateAt.END);
            Animation animation = new Animation() {
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) {
                    ViewGroup.LayoutParams params = ExpandTextView.this.getLayoutParams();
                    params.height = mStart + (int) ((mEnd - mStart) * (1 - interpolatedTime));
                    setLayoutParams(params);
                }
            };
            animation.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    mText.setTextColor(mTextColor);
                    mExpandText.setTextColor(mTextColor);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }
            });
            animation.setDuration(500);
            startAnimation(animation);
        }
    }

}

布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="12dp"
    android:paddingRight="12dp"
    android:background="@color/white">

    <TextView
        android:id="@+id/tv_info_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:paddingBottom="8dp"
        android:text="公司详情"
        android:textSize="16sp"
        android:textColor="@color/black"/>

    <com.bhy.test.view.ExpandTextView
        android:id="@+id/ex_tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_info_title">
    </com..bhy.test.view.ExpandTextView>

    <Button
        android:id="@+id/btn_info_expand"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/ex_tv_content"
        android:minHeight="0dp"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"
        android:background="@color/white"
        android:text="查看全部"
        android:textSize="14sp"
        android:textColor="@color/g69"/>

使用

public class MainActivity extends AppCompatActivity {

    private Button mBtnExpand;
    private ExpandTextView mExpandTextview;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.item_company_details_info);
        mBtnExpand = findViewById(R.id.btn_info_expand);
        mExpandTextview = findViewById(R.id.ex_tv_content);
        mExpandTextview.setText("中国专业IT社区优快云 (Chinese Software Developer Network) 创立于1999年,致力于为中国软件开发者提供知识传播、在线学习、职业发展等全生命周期服务。 截止2018年12月,优快云拥有超过2600万+技术会员,论坛发帖数1000万+,技术资源700万+,Blog文章1400万+,新媒体矩阵粉丝数量600万+,合作上千家科技公司及技术社区。 优快云全职员工超过500名,分布在北京、上海、深圳、武汉、成都、江苏沭阳等地区。");
        mExpandTextview.setTextColor(R.color.g999);
        mExpandTextview.setTextSize(12);
        mExpandTextview.setTextMaxLine(3);
        mBtnExpand.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mExpandTextview.isExpand()){
                    mExpandTextview.retract();
                    mBtnExpand.setText("查看全部");
                } else {
                    mExpandTextview.expand();
                    mBtnExpand.setText("收起");
                }
            }
        });

    }

}

最后:

  1. 代码比较简陋,可以继续优化
  2. 界面样式可以根据需求自己定义
  3. 文本内容可以在项目中去动态获取
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值