幅がwrap content
のTextView
があります。このTextView
でテキストを設定しましたが、テキストは毎回同じ長さではありません。テキストが非常に長い場合は、1行のtrueとellipsize
:endを使用します。しかし今、私は問題を抱えています。他のレイアウトの可視性を設定したいのですが、それはテキストの長さによって異なります。テキストが長すぎて画面に収まらない場合は、Visibleをtrueに設定しますが、テキストが短く、ellipsizeが必要ない場合は、可視性をfalseに設定します。そのため、TextViewのステータスを確認する必要があります。その楕円サイズがsetVisible
trueである場合、setVisible
falseでない場合。どうすればそれができますか。これは私が得たものです:
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);
}
しかし、この解決策は機能しません。
提供されているこのメソッドを使用できます: 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()を介して取得できます。
受け入れられたソリューションは機能しますが、楕円形の文字の最後の行のみをチェックするため、いくつかのコーナーケースを見逃しています。 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;
}
ただし、まだ改善の余地があります。しかし、この方法は私のユースケースで十分です。訂正と改善を歓迎します。 :-)
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が長すぎるかどうかを保存できます。そうではありません。テキストビューは正しい行数で再び描画され、フラグで楕円形になっているかどうかがわかります。
その後、isEllipsizedフラグを使用して、必要なことをすべて実行できます。