0

I try to create a "square" ConstraintLayout by extending the ConstraintLayout class as follows:

class SCConstraintLayout extends android.support.constraint.ConstraintLayout {
public SCConstraintLayout(Context context) {
    super(context);
}

public SCConstraintLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public SCConstraintLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int chosenDimension = 0;
    int mode = 0;

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        chosenDimension = MeasureSpec.getSize(heightMeasureSpec);
        mode = MeasureSpec.getMode(heightMeasureSpec);
    } else {
        chosenDimension = MeasureSpec.getSize(widthMeasureSpec);
        mode = MeasureSpec.getMode(widthMeasureSpec);
    }

    int side = MeasureSpec.makeMeasureSpec(chosenDimension, mode);

    super.onMeasure(side, side);
    setMeasuredDimension(side, side);
}
}

If I include a widget with this custom class into a chain of widgets such as in the following landscape-oriented layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:id="@+id/scMainFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
app:layout_optimizationLevel="chains"
tools:context=".MainActivity"
tools:layout_behavior="@string/appbar_scrolling_view_behavior">

<!-- gridFrame -->
<android.support.constraint.ConstraintLayout
    android:id="@+id/gridFrame"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintHorizontal_chainStyle="spread_inside"
    app:layout_constraintVertical_chainStyle="spread_inside"
    app:layout_optimizationLevel="chains"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/Report"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    >

    <!-- column headers  -->
    <android.support.constraint.ConstraintLayout
        android:id="@+id/colHeaders"
        android:layout_width="0dp"
        android:layout_height="14dp"
        android:orientation="horizontal"
        app:layout_constraintVertical_chainStyle="spread_inside"
        app:layout_optimizationLevel="chains"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/SCFrame"
        app:layout_constraintLeft_toLeftOf="@+id/SCFrame"
        app:layout_constraintRight_toRightOf="@+id/SCFrame"
        >

        <TextView
            android:id="@+id/textView0"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:gravity="center"
            android:text="A"
            android:background="#FF0000"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            />
        </android.support.constraint.ConstraintLayout>

    <!-- row headers  -->
    <android.support.constraint.ConstraintLayout
        android:id="@+id/rowHeaders"
        android:layout_width="14dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_optimizationLevel="chains"
        app:layout_constraintTop_toTopOf="@+id/SCFrame"
        app:layout_constraintBottom_toBottomOf="@+id/SCFrame"
        app:layout_constraintRight_toLeftOf="@+id/SCFrame"
        app:layout_constraintLeft_toLeftOf="parent"
        >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:gravity="center"
            android:text="1"
            android:background="#FF0000"
            app:layout_constraintVertical_chainStyle="spread_inside"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            />
        </android.support.constraint.ConstraintLayout>


        <be.ema.sclibrary.SCConstraintLayout
            android:id="@+id/SCFrame"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="#00FF00"
            app:layout_constraintLeft_toRightOf="@+id/rowHeaders"
            app:layout_constraintTop_toBottomOf="@id/colHeaders"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            >

            <TextView
                android:id="@+id/A1"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:text="this is A1"
                android:background="#0000FF"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                />
        </be.ema.sclibrary.SCConstraintLayout>
    </android.support.constraint.ConstraintLayout>

<TextView
    android:id="@+id/Report"
    android:layout_width="200dp"
    android:layout_height="0dp"
    android:text="This is the report"
    android:background="#FFFF00"
    app:layout_constraintLeft_toRightOf="@+id/gridFrame"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    />

</android.support.constraint.ConstraintLayout>

and if I display it on a "Nexus 6" in the emulator of Android Studio for instance it looks like the SCFrame is only partially square:

  • the A1 TextView is square (i.e. its width is equal to its height)
  • however the width of the SCFrame itself is different from its height

How should I change the SCConstraintLayout class or the xml lay-out to get the SCFrame view perfectly square (i.e. its width is equal to its height) when displayed on a device?

NB: in my real application, SCFrame has several rows and columns. And there are several other widgets like buttons and textviews instead of the Report textview.

ema3272
  • 1,021
  • 2
  • 13
  • 28

1 Answers1

1

You just need the top level to be a ConstraintLayout. The nested ones and the custom class aren't needed. As for the square-shaped TextView, you can use the aspect ratio attribute.

Rami Jemli
  • 2,550
  • 18
  • 31
  • Yes, the "aspect ratio" attribute is the solution. I overlooked this attribute because I am converting a previous layout from RelativeLayout to ConstraintLayout. Thank you – ema3272 May 23 '17 at 06:37