69

テキストビューの行数を取得したい

textView.setText("Test line 1 Test line 2 Test line 3 Test line 4 Test line 5.............")

textView.getLineCount();常にゼロを返す

それから私も試しました:

ViewTreeObserver vto = this.textView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
        ViewTreeObserver obs = textView.getViewTreeObserver();
        obs.removeGlobalOnLayoutListener(this);
        System.out.println(": " + textView.getLineCount());

    }
});

正確な出力を返します。

ただし、これは静的レイアウトでのみ機能します。

レイアウトを動的に膨張させているとき、これはもう機能しません。

TextView の行数を調べるにはどうすればよいですか?

4

10 に答える 10

107

getLineCount()次のように、を使用して 0 を返さないようにすることができましたpost

textview.setText(“Some text”);
textview.post(new Runnable() {
    @Override
    public void run() {
        int lineCount = textview.getLineCount();
        // Use lineCount here
    }
});
于 2015-09-01T20:49:42.117 に答える
40

この投稿で述べたように、

getLineCount()レイアウトパスの後でのみ、正しい行数が得られます。

TextViewこれは、メソッドを呼び出す前に最初のものをレンダリングする必要があることを意味しますgetLineCount()

于 2012-08-20T12:16:07.350 に答える
22
 textView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

        @Override
        public boolean onPreDraw() {
            // Remove listener because we don't want this called before _every_ frame
            textView.getViewTreeObserver().removeOnPreDrawListener(this)

            // Drawing happens after layout so we can assume getLineCount() returns the correct value
            if(textView.getLineCount() > 2) {
                // Do whatever you want in case text view has more than 2 lines
            }  

            return true; // true because we don't want to skip this frame
        }
});
于 2017-07-22T07:36:47.753 に答える
10

この質問の核心は、人々が TextView のサイズを事前に調べて、テキストにうまく収まるように動的にサイズを変更できるようにしたいということだと思います。典型的な用途は、吹き出しを作成することです (少なくとも、私が取り組んでいたのはそれでした)。

ここで説明した getTextBounds() と measureText() の使用など、いくつかの解決策を試しました。残念ながら、どちらの方法も少し不正確で、改行や未使用の行スペースを考慮する方法がありません。ということで、その方法は諦めました。

getLineCount() の問題は、getLineCount() が行数を取得する前にテキストを「レンダリング」する必要があることです。リスナーとレイアウトに関するさまざまなソリューションを読みましたが、もっと単純なものがないとは信じられませんでした。

2 日間いじった後、ようやく探していたものを見つけました (少なくとも、私にとってはうまくいきます)。すべては、テキストを「レンダリング」することが何を意味するかにかかっています。テキストが画面上に表示されなければならないという意味ではなく、内部で表示できるように準備する必要があるだけです。これは、invalidate() が直接呼び出されたとき、または TextView で setText() を実行したときのように間接的に呼び出されたときはいつでも発生します。

とにかく、ここに重要なコードがあります (フォントに基づいて、吹き出しの単一行の lineWidth と lineHeight を既に知っていると仮定します):

TextView talkBubble;
// No peeking while we set the bubble up.
talkBubble.setVisibility( View.INVISIBLE );
// I use FrameLayouts so my talk bubbles can overlap
// lineHeight is just a filler at this point
talkBubble.setLayoutParams( new FrameLayout.LayoutParams( lineWidth, lineHeight ) );
// setText() calls invalidate(), which makes getLineCount() do the right thing.
talkBubble.setText( "This is the string we want to dynamically deal with." );
int lineCount = getLineCount();
// Now we set the real size of the talkBubble.
talkBubble.setLayoutParams( new FrameLayout.LayoutParams( lineWidth, lineCount * lineHeight ) );
talkBubble.setVisibility( View.VISIBLE );

とにかく、それだけです。次の再描画では、テキストに合わせて作成されたバブルが表示されます。

注: 実際のプログラムでは、テキストの行を決定するために別のバブルを使用して、実際のバブルの長さと幅の両方のサイズを動的に変更できるようにします。これにより、短いステートメントなどでバブルを左から右に縮小できます。

楽しみ!

于 2013-07-12T14:43:19.457 に答える
8

@secnelis のアイデアに基づいて、API 11 以降を対象とする場合、さらにクリーンな方法があります。

a を拡張する代わりに、TextView既に組み込まれている機能を使用できます。View.OnLayoutChangeListener

ListAdapter.getView()たとえば、

if (h.mTitle.getLineCount() == 0 && h.mTitle.getText().length() != 0) {
    h.mTitle.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(final View v, final int left, final int top,
                final int right, final int bottom, final int oldLeft,
                final int oldTop, final int oldRight, final int oldBottom) {
            h.mTitle.removeOnLayoutChangeListener(this);
            final int count = h.mTitle.getLineCount();
            // do stuff
        }
    });
} else {
    final int count = h.mTitle.getLineCount();
    // do stuff
}
于 2016-03-14T13:33:12.237 に答える
4

この関数を使用して行数を計算することもできます。

private fun countLines(textView: TextView): Int {
        return Math.ceil(textView.paint.measureText(textView.text.toString()) /
                textView.measuredWidth.toDouble()).toInt()
    }

ただし、うまく機能しない場合があることに注意してくださいRecyclerView

于 2019-05-30T17:16:49.097 に答える
0

これをやっていますonCreateか?ビューはまだレイアウトされていないgetLineCount()ため、しばらくの間 0 です。Window LifeCycle の後半でこれを行うと、行数が得られます。あなたはそれを行うのに苦労するでしょうが、onCreate通常、onWindowFocusChangedこれhasFocus=trueまでにビューが測定されています.

提案textView.post()もいいですね

于 2016-02-26T18:19:45.387 に答える