كيفية التعامل مع الأوزان في 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 سوف يكون دائما أقل من 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 هو في الواقع يسمى مرتين عندما android:layout_weight
يتم تعيين.اكتشفت لاحقا انه ذكر في كيف الروبوت توجه وجهات النظر أن measure()
يمكن أن يسمى أي عدد من المرات أنه لم يكن على الفور الجلوس في ذهني.أول تمريرة من الواضح أنه لا يمكن إعطاء قيمة حجم كل طفل ، لأنه لا يعرف ما أوزان كل من رأي هذا أشقاء.فإنه يذهب من خلال ذلك مرة واحدة و يعطي عرض 0 مع MeasureSpec.غير محدد لمعرفة ما إذا كان الطفل لديه أي قيود محددة ، ثم يمر مرة أخرى تعيين الأوزان الفعلية مع 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);
}