20

私はTextView幅を持っていwrap contentます。これTextViewでテキストを設定しましたが、テキストは毎回同じ長さではありません。テキストが非常に長い場合は、trueとellipsize:endの1行を使用します。しかし今、私は問題を抱えています。他のレイアウトの可視性を設定したいのですが、それはテキストの長さによって異なります。テキストが長すぎて画面に収まらない場合は、Visibleをtrueに設定しますが、テキストが短く、ellipsizeが不要な場合は、可視性をfalseに設定します。そのため、TextViewのステータスを確認する必要があります。その楕円サイズが真になりたいsetVisibleとき、偽ではないときsetVisible。どうすればそれができますか。これは私が得たものです:

tvAle.post(new Runnable() {

        @Override
        public void run() {

            int lineCount    = tvAle.getLineCount();
            Paint paint =  new Paint();
            paint.setTextSize(tvAle.getTextSize());
            final float size = paint.measureText(tvAle.getText().toString());
            Log.v("a", ""+size+" "+tvAle.getWidth());
            if ((int)size > (tvAle.getWidth()+10)) {
                allergiesLayout.setVisibility(View.VISIBLE);
            }

            else
                allergiesLayout.setVisibility(View.GONE);

        }

しかし、この解決策は機能しません。

4

3 に答える 3

66

提供されているこのメソッドを使用できます: getEllipsisCount

Layout layout = textview1.getLayout();
if(layout != null) {
    int lines = layout.getLineCount();
    if(lines > 0) {
        int ellipsisCount = layout.getEllipsisCount(lines-1);
        if ( ellipsisCount > 0) {
            Log.d(TAG, "Text is ellipsized");
        } 
    } 
}

行は getLineCount() を介して取得できます

于 2013-03-22T10:02:36.010 に答える
14

まあ、受け入れられた解決策は機能しますが、省略文字の最後の行のみをチェックするため、いくつかのコーナーケースを見逃しています. 2 行で構成される TextView があり、TruncateAt.STARTを使用してテキストの先頭を切り捨てると、受け入れられた回答は失敗します。:-/

ViewTreeObserver.OnPreDrawListenerを追加することは、私にとって本当に高価なオーバーヘッドのように思えます。そこで、受け入れられた回答のコードに次の改善を加えました。

/**
 * Checks if the text of the supplied {@link TextView} has been ellipsized.
 *
 * @param textView
 *         The {@link TextView} to check its text.
 *
 * @return {@code True} if the text of the supplied {@code textView} has been ellipsized.
 */
public static boolean isTextViewEllipsized(final TextView textView) {
    // Check if the supplied TextView is not null
    if (textView == null) {
        return false;
    }

    // Check if ellipsizing the text is enabled
    final TextUtils.TruncateAt truncateAt = textView.getEllipsize();
    if (truncateAt == null || TextUtils.TruncateAt.MARQUEE.equals(truncateAt)) {
        return false;
    }

    // Retrieve the layout in which the text is rendered
    final Layout layout = textView.getLayout();
    if (layout == null) {
        return false;
    }

    // Iterate all lines to search for ellipsized text
    for (int line = 0; line < layout.getLineCount(); ++line) {

        // Check if characters have been ellipsized away within this line of text
        if (layout.getEllipsisCount(line) > 0) {
            return true;
        }
    }

    return false;
}

ただし、まだ改善の余地があります。しかし、この方法は私のユースケースには十分です。修正と改善を歓迎します。:-)

于 2015-11-03T12:23:01.883 に答える
2

getEllipsisCount を使用しても、空の行が含まれるテキストでは機能しません。次のコードを使用して動作させました:

message.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {

            if(m.isEllipsized == -1) {
                Layout l = message.getLayout();
                if (message.getLineCount() > 5) {
                    m.isEllipsized = 1;
                    message.setMaxLines(5);
                    return false;
                } else {
                    m.isEllipsized = 0;
                }
            }
            return true;
        }
    });

XML で maxLineCount を設定しないようにしてください。次に、コードで lineCount を確認し、それが特定の数より大きい場合は、false を返して TextView の描画をキャンセルし、行数と、textView が長すぎるかどうかを保存するフラグを設定できます。いいえ。textview は正しい行数で再度描画され、フラグで省略されているかどうかがわかります。

その後、isEllipsized フラグを使用して、必要なことを行うことができます。

于 2015-02-14T17:24:20.763 に答える