0

Not its separate components, but the dimension ratio of the ConstraintLayout itself, or a group of elements together.

I'm fallowing this excellent tutorial to build a RecyclerView with GridLayoutManager and two CardView columns that span the entire width of their container, each CardView (square) contains an ImageView (also square) and a TextView.

So, I need the CardView width to be "match parent" and get the same height (to be square), and the same goes for the ImageView. Something like this:

But this is what I have so far (note that CardView are not square):

This is my item layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="wrap_content"
    app:cardPreventCornerOverlap="true"
    app:cardUseCompatPadding="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="8dp">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/ic_home_black_24dp" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:gravity="center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

I know about app:layout_constraintDimensionRatio="1:1", but this is for use on any element within a ConstraintLayout, for example on my ImageView, not on ConstraintLayout itself.

I think I can invert my layout, put the CardView inside the ConstraintLayout and apply the above property to the CardView, but then I'm going to need another ConstraintLayout inside the CardView to place the ImageView and TextView properly, and I think it's not a good idea to nest ConstraintLayout.

Any suggestions?

lcnicolau
  • 3,252
  • 4
  • 36
  • 53

1 Answers1

2

Try the item layout below. I have constraints the ImageView relative to TextView. It should work. Or maybe you have to add some margin to ImageView. Give it a try.

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:cardPreventCornerOverlap="true"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintTop_toTopOf="parent"
        app:cardUseCompatPadding="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:padding="8dp"
            android:layout_height="match_parent">

            <ImageView
                android:id="@+id/imageView"
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintDimensionRatio="1:1"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                android:background="@color/colorPrimary"
                android:layout_marginBottom="8dp"
                app:layout_constraintBottom_toTopOf="@+id/textView" />

            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="23sp"
                android:text="Hello world"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent" />

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>
lcnicolau
  • 3,252
  • 4
  • 36
  • 53
ADM
  • 20,406
  • 11
  • 52
  • 83
  • Yeah, it works, but this is exactly my idea at the end of the question: _"I think I can invert my layout, put the `CardView` inside the `ConstraintLayout` and apply the above property (`app:layout_constraintDimensionRatio="1:1"`) to the `CardView` (...)"_. So, the question here would be if it is correct to do it this way (nesting one `ConstraintLayout` within another), or as I believe, we would be negating the `ConstraintLayout`'s purpose of keeping a flat layout. – lcnicolau Apr 21 '20 at 04:09
  • yeah but in this case nesting is required. because Root layout is dynamic . have a look at [This thread](https://stackoverflow.com/questions/8981029/simple-way-to-do-dynamic-but-square-layout) . You will find similar answers .. – ADM Apr 21 '20 at 04:55