1. 程式人生 > >Textview多行時,最後結尾處顯示省略號

Textview多行時,最後結尾處顯示省略號

一般情況寫,在設定Textview最大行數和結尾處顯示省略號以後,預設是會在結尾處顯示省略號的。這裡不用系統預設的,而是自己拼省略號,以滿足某些實際需求。文章最後附onWindowFocusChanged()生命週期。

效果圖:
這裡寫圖片描述

程式碼實現(2種方式):
佈局是一樣的:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/activity_main"
    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_marginTop="30dp" android:lineSpacingMultiplier
="1.4" android:textSize="20sp" />
<TextView android:id="@+id/result_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:lineSpacingMultiplier="1.4" android:textSize
="20sp" />
</LinearLayout>

程式碼實現:
第一種方法:

package com.chen.animdemo;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView textview;
    private TextView result_tv;

    private String s;

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

        s = "0123456789012345678901234567890123456789012345678901234567890123456789";

        textview = (TextView) findViewById(R.id.textview);
        result_tv = (TextView) findViewById(R.id.result_tv);

        textview.setText(s);

    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        TextPaint paint = textview.getPaint();

        int paddingLeft = textview.getPaddingLeft();
        int paddingRight = textview.getPaddingRight();

        //給省略號留的長度(但是,因為字元佔位問題,獲取的這個長度,要比省略號的三個點的長度大一些)
        float moreText = textview.getTextSize() * 3;

        //乘2,是代表2行的意思,減去moreText,是給省略號預留一點位置
        float availableTextWidth = (textview.getWidth() - paddingLeft - paddingRight) * 2 - moreText;
        /**
         * TextUtils中public static CharSequence ellipsize(CharSequence text,TextPaint p,float avail, TruncateAt where)說明
         *
         * Returns the original(原始) text if it fits(適合、符合) in the specified(指定) width
         * given the properties(性質) of the specified(指定) Paint,
         * or, if it does not fit, a truncated(縮短了的,被刪截的)
         * copy with ellipsis(省略、省略符號) character added at the specified(指定) edge(邊緣) or center.
         */
        CharSequence ellipsizeStr = TextUtils.ellipsize(s, paint, availableTextWidth, TextUtils.TruncateAt.END);

        Log.e("textview.getTextSize()", textview.getTextSize() + "");
        Log.e("moreText", moreText + "");
        Log.e("textview.getWidth()", textview.getWidth() + "");
        Log.e("paddingLeft", paddingLeft + "");
        Log.e("paddingRight", paddingRight + "");
        Log.e("availableTextWidth", availableTextWidth + "");
        Log.e("ellipsizeStr", ellipsizeStr + "");

        result_tv.setText(ellipsizeStr);
    }
}

第二種方法:

package com.chen.animdemo;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.TextView;

public class MainActivity2 extends Activity {

    private TextView textview;
    private TextView result_tv;

    private String s;

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

        s = "0123456789012345678901234567890123456789012345678901234567890123456789";

        textview = (TextView) findViewById(R.id.textview);
        result_tv = (TextView) findViewById(R.id.result_tv);

        textview.setText(s);

        textview.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                //一般用完之後,立即移除該監聽
                textview.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                TextPaint paint = textview.getPaint();

                int paddingLeft = textview.getPaddingLeft();
                int paddingRight = textview.getPaddingRight();

                //給省略號留的長度(但是,因為字元佔位問題,獲取的這個長度,要比省略號的三個點的長度大一些)
                float moreText = textview.getTextSize() * 3;

                //乘2,是代表2行的意思,減去moreText,是給省略號預留一點位置
                float availableTextWidth = (textview.getWidth() - paddingLeft - paddingRight) * 2 - moreText;
                /**
                 * TextUtils中public static CharSequence ellipsize(CharSequence text,TextPaint p,float avail, TruncateAt where)說明
                 *
                 * Returns the original(原始) text if it fits(適合、符合) in the specified(指定) width
                 * given the properties(性質) of the specified(指定) Paint,
                 * or, if it does not fit, a truncated(縮短了的,被刪截的)
                 * copy with ellipsis(省略、省略符號) character added at the specified(指定) edge(邊緣) or center.
                 */
                CharSequence ellipsizeStr = TextUtils.ellipsize(s, paint, availableTextWidth, TextUtils.TruncateAt.END);

                Log.e("textview.getTextSize()", textview.getTextSize() + "");
                Log.e("moreText", moreText + "");
                Log.e("textview.getWidth()", textview.getWidth() + "");
                Log.e("paddingLeft", paddingLeft + "");
                Log.e("paddingRight", paddingRight + "");
                Log.e("availableTextWidth", availableTextWidth + "");
                Log.e("ellipsizeStr", ellipsizeStr + "");

                result_tv.setText(ellipsizeStr);

            }
        });

    }

}

資料列印:

 E/textview.getTextSize(): 55.0
 E/moreText: 165.0
 E/textview.getWidth(): 1080
 E/paddingLeft: 0
 E/paddingRight: 0
 E/availableTextWidth: 1995.0
 E/ellipsizeStr: 012345678901234567890123456789012345678901234567890123456789012…

說明:
在上面的計算方法中,有這樣一句:

float availableTextWidth = (textview.getWidth() - paddingLeft - paddingRight) * 2 - moreText;

最後為什麼要減去 moreText呢?
將上述任一方法的該句改為:

float availableTextWidth = (textview.getWidth() - paddingLeft - paddingRight) * 2

效果圖如下(注意省略號的出現位置):
這裡寫圖片描述

資料列印如下:

 E/textview.getTextSize(): 55.0
 E/moreText: 165.0
 E/textview.getWidth(): 1080
 E/paddingLeft: 0
 E/paddingRight: 0
 E/availableTextWidth: 2160.0
 E/ellipsizeStr: 01234567890123456789012345678901234567890123456789012345678901234567…

———————————————————————————————

onWindowFocusChanged()宣告週期:

啟動

03-20 10:49:00.608 3392-3392/com.chen.animdemo E/chen: onCreate
03-20 10:49:00.609 3392-3392/com.chen.animdemo E/chen: onStart
03-20 10:49:00.611 3392-3392/com.chen.animdemo E/chen: onResume
03-20 10:49:00.654 3392-3392/com.chen.animdemo E/chen: onWindowFocusChanged

home鍵
03-20 10:49:21.899 3392-3392/com.chen.animdemo E/chen: onWindowFocusChanged
03-20 10:49:21.902 3392-3392/com.chen.animdemo E/chen: onPause
03-20 10:49:22.232 3392-3392/com.chen.animdemo E/chen: onStop

回來
03-20 10:49:47.842 3392-3392/com.chen.animdemo E/chen: onRestart
03-20 10:49:47.846 3392-3392/com.chen.animdemo E/chen: onStart
03-20 10:49:47.847 3392-3392/com.chen.animdemo E/chen: onResume
03-20 10:49:47.860 3392-3392/com.chen.animdemo E/chen: onWindowFocusChanged

鎖屏
03-20 10:50:01.250 3392-3392/com.chen.animdemo E/chen: onPause
03-20 10:50:01.326 3392-3392/com.chen.animdemo E/chen: onStop
03-20 10:50:02.788 3392-3392/com.chen.animdemo E/chen: onWindowFocusChanged

開屏
03-20 10:50:21.452 3392-3392/com.chen.animdemo E/chen: onRestart
03-20 10:50:21.471 3392-3392/com.chen.animdemo E/chen: onStart
03-20 10:50:21.472 3392-3392/com.chen.animdemo E/chen: onResume
03-20 10:50:21.515 3392-3392/com.chen.animdemo E/chen: onWindowFocusChanged

注:
在這個方法中,可以獲得任何介面上任何控制元件的寬高資料,且不用再次測量,因為走到這個方法裡,就是已經測量並擺放完畢的。但是,如果實際需求中,你剛剛進入這個介面,就需要獲取一些控制元件的寬高去做一些操作,就不要用這個方法了,因為通過它獲取控制元件寬高資料,有延時