morristech
1/10/2018 - 8:50 AM

Android; Mixing wrap_content and match_parent in a wrap_content FrameLayout

Android; Mixing wrap_content and match_parent in a wrap_content FrameLayout

/**
 * Wraps the inflated TextView, adds an ImageView programatically that matches_parent by force.
 * By default the FrameLayout would adjust it's bounds to the added ImageView, even if we add a 
 * LayoutParams with MATCH_PARENT. I omitted it here since it doesn't matter.
 *
 * @author Pär Amsen 07/2017
 */
public class CustomFrameLayout extends FrameLayout {
    public CustomFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        //add an ImageView that apparently ignores match_parent out of the box, I omitted it instead
        ImageView view = new ImageView(context);
        view.setBackground(ContextCompat.getDrawable(context, R.mipmap.ic_launcher_round));
        addView(view);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        View wrap = getChildAt(getChildCount() - 1); //The TextView to wrap in this case
        measureChild(wrap, widthMeasureSpec, heightMeasureSpec); //Measure it to get its exact dimens
        setMeasuredDimension(wrap.getMeasuredWidth(), wrap.getMeasuredHeight()); //We're wrapping it, so use those as our dimens

        for (int i = 0; i < getChildCount() - 1; i++) {
            //Everyone else, match parent
            measureChild(getChildAt(i),
                    MeasureSpec.makeMeasureSpec(wrap.getMeasuredWidth(), MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(wrap.getMeasuredHeight(), MeasureSpec.EXACTLY));
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.paramsen.testgroundjava.MainActivity">

    <com.paramsen.testgroundjava.view.CustomFrameLayout
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </com.paramsen.testgroundjava.view.CustomFrameLayout>

</FrameLayout>