文字末尾加图片按钮,点击按钮打开折叠文字,设置文字显示指定行数TextApp,textview结尾图片折叠文字

文字末尾加图片按钮,点击按钮打开折叠文字,设置文字显示指定行数TextApp,textview结尾图片折叠文字, 实现效果  把长文字 折叠成1行或者指定行显示,末尾加... + 图片,点击图片展开全部文字显示或者折叠成1行(或者指定行)显示。

上代码:

1、MainActivity.java

package com.android.textapp;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;


import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;


public class MainActivity extends AppCompatActivity {

    private String resourceStr;
    private String shortStr;
    private TextView textView;
    // 默认显示2行
    private int defaultLine = 2;
    private boolean expored = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        intView();
    }

    private void intView() {
        textView = findViewById(R.id.textView);
        textView.getViewTreeObserver().addOnPreDrawListener(new MyOnPreDrawListener());

         resourceStr = "国要要顺在要个有爱是你我,,可. 楷经?《要,》国要要顺在要个有爱是你我,,可. 楷经?《==要,》国要要顺在要个有爱是你我,,可. 楷经?《要,》国要要顺在要个有爱是你我,,可. 楷经?【《要,》国要要顺在要个有爱是你我,,可. 楷经?《要,》国要要顺在要个有爱是你我,,可. 楷经?】】《要,》国要要顺在要个有爱是你我,,可. 楷经?《要,》国要要顺在要个有爱是你我,,可. 、、楷经?《要,》国要要顺在要个有爱是你我,,可. 楷经?《要,》国要要顺在要个有爱是你我,,可.,楷经?《要,》国要要顺在要个有爱是你我,,可. 楷经?《要,》国要要顺在要个有爱是你我,,可. 楷经?《要,》" ;
        textView.setText(resourceStr);
        int num = getLineMaxNumber(getBaseContext(), textView);
        if (resourceStr.length() > num * defaultLine) {
            shortStr = subStringRows(getBaseContext(), textView, resourceStr , defaultLine);
        } else {
            shortStr = resourceStr;
        }
    }

    public class MyOnPreDrawListener implements ViewTreeObserver.OnPreDrawListener {
        @Override
        public boolean onPreDraw() {
            textView.getViewTreeObserver().removeOnPreDrawListener(this);
            int line = textView.getLineCount();
            Log.e("lines" , "lines= " + line);
            // 多行文字折叠处理
            if (line <= defaultLine) {
                textView.setText(resourceStr);
            } else {
                setIcon(expored, new MyClickableSpan());
            }
            return true;
        }
    };

    public class MyClickableSpan extends ClickableSpan {

        @Override
        public void onClick(@NonNull View widget) {
            expored = !expored;
            Log.e("MainActivity","textView图片点击------ widget.isSelected()= " + widget.isSelected() + " ,expored= " + expored);
            setIcon(expored, this);
        }
    }

    private void setIcon(boolean expored, MyClickableSpan myClickableSpan) {
        setIcon(expored, myClickableSpan, true);
    }


    private void setIcon(boolean expored, ClickableSpan clickableSpan, boolean hasImage) {
        int tvIconResId = 0;
        if (hasImage) {
            tvIconResId = expored ? R.mipmap.icon_arror_fold : R.mipmap.icon_arror_expand;
        }
        String inputStr;
        if (expored) {
            inputStr = resourceStr;
        } else {
            inputStr = shortStr;
        }
        textViewDrawableIcon(getBaseContext(), textView, inputStr.trim(), tvIconResId, clickableSpan);
    }


    /**
     * 在textview末尾增加图片,并增加图片的点击事件监听
     */
    private void textViewDrawableIcon(Context context, TextView tv, String input, int picResId,
                                      ClickableSpan clickableSpan) {
        if (context == null || tv == null) {
            return;
        }
        SpannableString ss = new SpannableString(input + " ");
        int len = ss.length();
        //图片
        Drawable d = ContextCompat.getDrawable(context, picResId);
        d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
        //构建ImageSpan
        ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
        ss.setSpan(span, len - 1, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        if (clickableSpan != null) {
            ss.setSpan(clickableSpan, len - 1, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        }
        tv.setText(ss);
        //需要设置这个才能点击
        tv.setMovementMethod(LinkMovementMethod.getInstance());
        //去掉高亮,不然点击时候背景会变高亮
        tv.setHighlightColor(context.getResources().getColor(android.R.color.transparent));
    }

    /**
     * 获取textview一行显示的文字数
     */
    private int getLineMaxNumber(Context context, TextView textView) {
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        int widthScreen = dm.widthPixels;
        int width = (widthScreen - dip2px( 28));
        int num = Math.round(width / textView.getTextSize());
        return num;
    }

    private int dip2px(int dxValue) {
        float  mScale = getResources().getDisplayMetrics().density;
        return (int) (dxValue * mScale + 0.5f);
    }

    /**
     * 截取textView显示的文字的指定行数,例如:截取前3行文字。
     * @param line  要截取的行数
     */
    private String subStringRows(Context context, TextView textView, String sourceStr, int line) {
        if (context == null) {
            return sourceStr;
        }
        if (TextUtils.isEmpty(sourceStr)) {
            return "";
        }
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        int screenwidth = dm.widthPixels;
        // 28 是textview 距离屏幕两侧间距
        int width = (screenwidth - dip2px( 28));
        TextPaint paint = textView.getPaint();
        int wordwidth = (int)paint.measureText("a",0,1);
        int num = (int) (width/wordwidth);
        sourceStr = sourceStr.substring(0, (num * line)/2-3) + "...";
        return replaceAllSpecialCharacters(sourceStr);
    }

    private String replaceAllSpecialCharacters(String sourceStr) {
        if (TextUtils.isEmpty(sourceStr)) {
            return "";
        }
        sourceStr = sourceStr.replace("\\s","")
                .replace("\n","")
                .replace("\t","")
                .replace("\r","");
        return sourceStr;
    }
}

2、布局文件  activity_main2.xml

<?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/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="14dp"
        android:layout_marginTop="140dp"
        android:layout_marginEnd="14dp"
        android:text=""
        android:textColor="#000000"
        android:textSize="14sp" />
</LinearLayout>

图片资源: 

源码下载地址;

(文字末尾加图片按钮,点击按钮打开折叠文字,设置文字显示指定行数TextApp-Android文档类资源-CSDN下载)