仿微信可折叠效果的TextView

本文介绍了一种可折叠TextView的实现方法,通过自定义View组件,实现了文本内容超过设定行数时显示“全文”按钮,点击后展开全部内容,并提供代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在微信朋友圈中,发送大量的文本信息时,在展示的时候微信会将该文本信息进行折叠处理,出现“全文”,“收起”的操作提示。当点击全文时,才能看到全部的文本信息,正好最近的项目中也提出了类似的需求,这里就对该自定义View的实现的方法进行了整理。

代码如下:
1.自定义的View:

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
 * 可折叠的textview
 */
public class ExpandTextView extends LinearLayout {
    public static final int DEFAULT_MAX_LINES = 3;
    private TextView contentText;
    private TextView textPlus;
    private int showLines;
    private ExpandStatusListener expandStatusListener;
    private boolean isExpand;

    public ExpandTextView(Context context) {
        super(context);
        initView();
    }

    public ExpandTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
        initView();
    }

    public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs);
        initView();
    }

    private void initAttrs(AttributeSet attrs) {
        TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.ExpandTextView, 0, 0);
        try {
            showLines = typedArray.getInt(R.styleable.ExpandTextView_showLines, DEFAULT_MAX_LINES);
        }finally {
            typedArray.recycle();
        }
    }

    private void initView() {
        setOrientation(LinearLayout.VERTICAL);
        LayoutInflater.from(getContext()).inflate(R.layout.layout_magic_text, this);
        contentText = (TextView) findViewById(R.id.contentText);
        if(showLines > 0){
            contentText.setMaxLines(showLines);
        }

        textPlus = (TextView) findViewById(R.id.textPlus);
        textPlus.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                String textStr = textPlus.getText().toString().trim();
                if("全文".equals(textStr)){
                    contentText.setMaxLines(Integer.MAX_VALUE);
                    textPlus.setText("收起");
                    setExpand(true);
                }else{
                    contentText.setMaxLines(showLines);
                    textPlus.setText("全文");
                    setExpand(false);
                }
                //通知外部状态已变更
                if(expandStatusListener != null){
                    expandStatusListener.statusChange(isExpand());
                }
            }
        });
    }

    public void setText(final CharSequence content){

        //在开始绘制contentText内容时,进行监听
        contentText.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

            @Override
            public boolean onPreDraw() {
                // 避免重复监听
                contentText.getViewTreeObserver().removeOnPreDrawListener(this);
                //获取当前文本的行数
                int linCount = contentText.getLineCount();
                if(linCount > showLines){

                    if(isExpand){
                        contentText.setMaxLines(Integer.MAX_VALUE);
                        textPlus.setText("收起");
                    }else{
                        contentText.setMaxLines(showLines);
                        textPlus.setText("全文");
                    }
                    textPlus.setVisibility(View.VISIBLE);
                }else{
                    textPlus.setVisibility(View.GONE);
                }
                return true;
            }


        });
        contentText.setText(content);
    }

    public void setExpand(boolean isExpand){
        this.isExpand = isExpand;
    }

    public boolean isExpand(){
        return this.isExpand;
    }

    public void setExpandStatusListener(ExpandStatusListener listener){
        this.expandStatusListener = listener;
    }

    public interface ExpandStatusListener{
        void statusChange(boolean isExpand);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return textPlus.dispatchTouchEvent(event);
    }
}

2.相关布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <TextView
        android:id="@+id/contentText"
        android:textSize="18sp"
        android:textColor="#000000"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""/>

    <TextView
        android:id="@+id/textPlus"
        android:textSize="18sp"
        android:textColor="#666666"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:text=""/>

</LinearLayout>

3.自定义属性

    <declare-styleable name="ExpandTextView">
        <attr name="showLines" format="integer"/>
    </declare-styleable>

4.开始引用

    <mo.yumf.com.myviews.ExpandTextView
        android:id="@+id/expandTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:showLines="4"/>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值