カスタムビューのonmeasueで重みを処理する方法は?
-
14-11-2019 - |
質問
私はその子のフォントサイズを拡大縮小するカスタムビューを作成しています TextViews
すべてを設定された幅に収まるように、それぞれが独自の行にあります。明らかにそれを理解するために幅が必要になるでしょう。
私はオーバーライドしました onMeasure()
そうのように:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int lineWidth = widthSize - getPaddingLeft() - getPaddingRight();
// Change the text size until the largest line of text fits.
while (lineWidth < calculateTextWidth()) {
for (TextView textView : this.childViews) {
float newSize = textView.getTextSize() - 1;
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, newSize);
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
calculateTextWidth()
テキストの最大行の幅を計算し、すべてがそれで動作します。このコードは正常に動作しています FILL_PARENT
と WRAP_CONTENT
幅が、私はコンポーネントに重量を与え、それがそのようにその重量を自動設定させようとすると、ネジアップします。
MeasureSpec.getSize(widthMeasureSpec)
戻り値 0
, 、として getMinimumSuggestedWidth()
あまりにも、ありません。これは、lineWidthが常により小さくなるため、素晴らしいActivity Not Respondingエラーを与えます calculateTextWidth()
これまでに戻ってくるので、 while
ループは永遠に実行されます。私が使用したXMLコードは、本質的にこれでした:
<com.my.widgets.ScalingTextViewGroup
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:gravity="center_horizontal"
>
<TextView
android:id="@+id/text_1"
android:text="Text 1"
android:textSize="20sp" />
<TextView
android:id="@+id/text_2"
android:text="Text 2"
android:textSize="18sp" />
<TextView
android:id="@+id/text_3"
android:text="Text 3"
android:textSize="18sp" />
<TextView
android:id="@+id/text_4"
android:text="Text 4"
android:textSize="18sp" />
</com.my.widgets.ScalingTextViewGroup>
私はそれが0を返す理由を理解しています-明らかに、それは0に設定されています-しかし、どのように私はそれを使用するのですか layout_weight
?私はそれが簡単な答えを持つべきものだと感じていますが、私はそれが何であるかについて途方に暮れています。
解決
私はいくつかの重要なグーグルを通してそれを理解することになりました。オン このページ 私はそれを知った onMeasureは実際には2回呼び出されます とき android:layout_weight
が設定されている。私は後でそれが言及されていることを知りました Androidがビューを描画する方法 それは... measure()
何度でも呼び出すことができます、それはすぐに私の脳に座っていませんでした。最初のパスは、ビューのすべての兄弟の重みが何であるかを知らないため、明らかに各子のサイズの値を与えることはできません。それは一度それを通過し、MeasureSpecで0の幅を与えます。子に特定の制約があるかどうかを確認するために指定されていない場合は、次のようになります また! MeasureSpecで実際の重みを割り当てるには。その通り!.私の活動は最初のパスで台無しになっていたので、レイアウトステップに到達することはありませんでした。私のonMeasure()を次のコードに修正すると、問題が修正されました。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.UNSPECIFIED) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int lineWidth = widthSize - getPaddingLeft() - getPaddingRight();
// Change the text size until the largest line of text fits.
while (lineWidth < calculateTextWidth()) {
for (TextView textView : this.childViews) {
float newSize = textView.getTextSize() - 1;
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, newSize);
}
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}