So my custom TextView is cutting off the last line of text in some cases. I'm using a custom font. It seems to only cut off the last word. I changed my custom text views to regular ones, which forces my text views to use standard fonts instead of my custom one, and suddenly the sizing works.
Theory on issue: While using the DDMS tool to see the layout sizes around my views and comparing custom font version vs regular font version, it looks like it measures the height of the characters properly--if it didn't it would cut off part of the y's, g's, and p's on my bigger, custom font. But then it doesn't properly guess the amount of lines my bigger font will take up, and measures the amount of lines as if it were the smaller, non-custom font. So when a string ends with a two letter word which is just on the edge of wrapping, it doesn't think it needs to wrap to the next line and cuts it off.
Layout for inside the ViewPager which includes the problem child CustomTextView:
<LinearLayout
android:id="@+id/header_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="-12dp"
android:paddingRight="-12dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
snip>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
snip>
<!---v--- this is the problem child--->
<com.snip.custom.views.CustomTextView
android:id="@+id/label"
style="@style/typographyParagraphBody"
android:layout_centerHorizontal="true"
android:gravity="center"
android:layout_marginBottom="20dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:text="@{carouselItemViewModel.label}"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
</LinearLayout>
Boring ViewPager:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height){
height = h;
}
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
My layout file:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@{carouselViewModel.carouselBackgroundColor}"
android:orientation="vertical">
<com.snip.custom.views.CustomTextView
android:id="@+id/text"
style="@style/irrelevant"
android:text="@{carouselViewModel.text}"/>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-17dp"
android:layout_gravity="top"
android:layout_below="@id/text"
app:tabBackground="@drawable/dot_tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"
app:tabPaddingEnd="5dp"
app:tabPaddingStart="5dp"
app:viewPager="@{{viewPager}}" />
<com.snip.custom.views.CustomViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingEnd="20dp"
android:paddingStart="20dp"
android:layout_below="@id/tab_layout"
app:currentItem="@{carouselViewModel.carouselCurrentItemSubject}"
app:setOffscreenPageLimit="@{carouselViewModel.carouselOffscreenPageLimitSubject}"
app:itemView="@{carouselViewModel.carouselItemViewSelector}"
app:items="@{carouselViewModel.carouselItems}"
app:onAdapterChangeListener="@{carouselViewModel.carouselAdapterChangeSubject}"
app:onPageChangeListener="@{carouselViewModel.carouselPageChangeSubject}"/>
</RelativeLayout>
Looks like I needed more code to measure the children properly, since they weren't aware of their layout parameters. So I remeasure them by applying the parent widthMeasureSpec.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height){
height = h;
}
height = Math.max(child.getMeasuredHeight(), measureViewHeight(child, widthMeasureSpec));
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private int measureViewHeight(View view, int widthMeasuredSpec) {
view.measure(getChildMeasureSpec(widthMeasuredSpec,
getPaddingLeft() + getPaddingRight(),
view.getLayoutParams().width),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
return view.getMeasuredHeight();
}