この質問の核心は、人々が 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 );
とにかく、それだけです。次の再描画では、テキストに合わせて作成されたバブルが表示されます。
注: 実際のプログラムでは、テキストの行を決定するために別のバブルを使用して、実際のバブルの長さと幅の両方のサイズを動的に変更できるようにします。これにより、短いステートメントなどでバブルを左から右に縮小できます。
楽しみ!