首先聲明:我是一個新手(如果哪里有誤,請輕噴)务豺,最近想做一個文本折疊功能,在網(wǎng)上看了很多嗦明,大多是用兩個TextView來實現(xiàn)笼沥,這種我覺得太難看,直接排除娶牌。
終于找到了一些一個TextView的奔浅,也是我的參考來源(嗯,沒錯诗良,是參考)汹桦,鏈接如下:
https://blog.csdn.net/figurers/article/details/82019646
https://blog.csdn.net/u011228060/article/details/83991089
https://www.cnblogs.com/qynprime/p/8026672.html
先放上效果圖(請忽略文本的背景):
這是顯示三行的文本
這是全部顯示的文本
看了上面幾篇文章,覺得這就是我想要的效果了鉴裹,可是覺得代碼不夠完美舞骆,于是自己小小的改動了一些,不知道能不能算做原創(chuàng)(姑且當作原創(chuàng)吧)径荔!
廢話不多說督禽,上代碼:
TextView的顯示隱藏?
????public class AdjustableTextView {
????private String string;
????//控件id
????private TextView textView;
????//設置要顯示的行數(shù)
????private int length;
????private String hiddenString;
????private String displayString;
????public AdjustableTextView(TextView textView, int length) {
????????this.textView = textView;
????????this.length = length;
????}
????public void hiddenText() {
????????string = textView.getText().toString();
????????//設置textView可點擊
????????textView.setMovementMethod(LinkMovementMethod.getInstance());
???????//注冊一個需要隱藏文本的Text的觀察者來監(jiān)聽視圖樹,防止報錯
????????ViewTreeObserver viewTreeObserver = textView.getViewTreeObserver();
???????/*interface ViewTreeObserver.OnGlobalLayoutListener
???????當在一個視圖樹中全局布局發(fā)生改變或者視圖樹中的某個視圖的可視狀態(tài)發(fā)生改變時总处,所要調(diào)用的回調(diào)函數(shù)的接口類??*/
????????viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
????????????@Override
????????????public void onGlobalLayout() {
?????????????//注冊一個需要隱藏文本的Text的觀察者來監(jiān)聽視圖樹
????????????????ViewTreeObserver viewTreeObserver = textView.getViewTreeObserver();
????????????//移除監(jiān)聽狈惫,防止后續(xù)繼續(xù)監(jiān)聽
????????????????viewTreeObserver.removeOnGlobalLayoutListener(this);
?????????????//如果文本的行數(shù)大于要求的行數(shù)
????????????????if (textView.getLineCount() > length) {
??????????//得到文本前三行最后一個字符的位置
????????????????????int lineEnd = textView.getLayout().getLineEnd(length - 1);
????????//拼接需要顯示的字符串
????????????????????hiddenString = string.substring(0, lineEnd - 5) + "...展開";
????????????????????textView.setText(getClickableSpan(lineEnd));
????????????????}
????????????}
????????});
????}
????private SpannableString getClickableSpan(int count) {
????????class Listener extends ClickableSpan implements View.OnClickListener {
?????//文字點擊事件
????????????@Override
????????????public void onClick(@NonNull View widget) {
????????????????textView.setText(string);
????????//調(diào)用顯示文本的拼接方法
????????????????displayText();
????????????}
????????????@Override
????????????public void updateDrawState(@NonNull TextPaint ds) {
????????????????super.updateDrawState(ds);
????????????????ds.setUnderlineText(false);
????????????}
????????}
????????SpannableString spannableString = new SpannableString(hiddenString);
????????//設置前景色為紅色
????????ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#ff0000"));
????????//設置字體大小
????????spannableString.setSpan(new RelativeSizeSpan(1.1f), count - 5, count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
????????//設置字體可點擊
????????spannableString.setSpan(new Listener(), count - 5, count, Spanned.SPAN_MARK_MARK);
????????//添加前景色為紅色
????????spannableString.setSpan(foregroundColorSpan, count - 5, count, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
????????return spannableString;
????}
????public void displayText() {
????????string = textView.getText().toString();
????????//設置textView可點擊
????????textView.setMovementMethod(LinkMovementMethod.getInstance());
?????????//注冊一個需要隱藏文本的Text的觀察者來監(jiān)聽視圖樹,防止報錯
????????ViewTreeObserver viewTreeObserver = textView.getViewTreeObserver();
????????/*interface ViewTreeObserver.OnGlobalLayoutListener
???????當在一個視圖樹中全局布局發(fā)生改變或者視圖樹中的某個視圖的可視狀態(tài)發(fā)生改變時鹦马,所要調(diào)用的回調(diào)函數(shù)的接口類??*/
????????viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
????????????@Override
????????????public void onGlobalLayout() {
???????????//注冊一個需要隱藏文本的Text的觀察者來監(jiān)聽視圖樹胧谈,防止報錯
????????????????ViewTreeObserver viewTreeObserver = textView.getViewTreeObserver();
????????????????//移除監(jiān)聽,防止后續(xù)繼續(xù)監(jiān)聽
????????????????viewTreeObserver.removeOnGlobalLayoutListener(this);
???????????//得到最后一個字符串的位置
????????????????int lineEnd2 = textView.getLayout().getLineEnd(textView.getLineCount() - 1);
????????????//在原字符串后面加上“隱藏”
????????????????displayString = string.substring(0, lineEnd2) + "隱藏";
????????????????textView.setText(getClickableSpan2(lineEnd2));
????????????}
????????});
????}
????private SpannableString getClickableSpan2(int count) {
????????????//指定部分監(jiān)聽
????????class Listener extends ClickableSpan implements View.OnClickListener {
???????????//點擊事件
????????????@Override
????????????public void onClick(@NonNull View widget) {
????????????????textView.setText(string);
????????????//調(diào)用隱藏文本的方法
????????????????hiddenText();
????????????}
????????????@Override
????????????public void updateDrawState(@NonNull TextPaint ds) {
????????????????super.updateDrawState(ds);
????????????????ds.setUnderlineText(false);
????????????}
????????}
????????//新建一個spannableString,把拼接好的字符串傳進去(設置字體顏色菠红,監(jiān)聽點擊第岖,字體大小)
????????SpannableString spannableString = new SpannableString(displayString);
????????//設置前景色為紅色
????????ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.parseColor("#ff0000"));
????????spannableString.setSpan(new RelativeSizeSpan(1.1f), count, count + 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
????????spannableString.setSpan(new Listener(), count, count + 2, Spanned.SPAN_MARK_MARK);
????????//添加前景色為紅色
????????spannableString.setSpan(foregroundColorSpan, count, count + 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
??????//返回 spannableString
????????return spannableString;
?????}
????}
使用方法相當簡單试溯,新建一個AdjustableTextView傳入控件id和需要的行數(shù)即可
AdjustableTextView adjustableTextView=new AdjustableTextView(控件id,行數(shù));
adjustableTextView.hiddenText();