1

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>
Zeek Aran
  • 523
  • 4
  • 18

1 Answers1

0

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();
}
Zeek Aran
  • 523
  • 4
  • 18
  • in the "if" of the for loop you assign height (height = h) and in the next line you assign height again. I think you can delete the if statement. – Emanuel Sep 27 '19 at 14:47