Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply aspect ratio from material design specs on a view?

I am designing an CardView for my app with a rich media header.

I try to make something like this:

Rich media header from google material design specification

According to google material design specification, the picture should have a 16:9 aspect ratio:

Google rich media header specification

So, my question, how to achieve this (Code or XML) ?

If I use a defined size, it will not be a real 16:9 aspect ratio and I will have to handle many resource files for all screen sizes and orientations.

Else, I did not succeed to set a size by code because in onBindViewHolder(...), getWidth() on my view return 0.

Any idea ?

like image 551
Zxcv Avatar asked Dec 05 '22 20:12

Zxcv


2 Answers

Now with both PercentFrameLayout and PercentRelativeLayout being deprecated in 26.0.0, you should consider using of ConstraintLayout to build out your cards.

Here is the xml snippet for your case:

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/CardView.Light"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginEnd="8dp">

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

        <ImageView
            android:id="@+id/media_image"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginTop="0dp"
            android:layout_marginEnd="0dp"
            android:layout_marginStart="0dp"
            android:layout_marginBottom="16dp"
            android:scaleType="centerCrop"
            app:srcCompat="@android:color/darker_gray"
            app:layout_constraintDimensionRatio="H,16:9"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/supporting_text"
            app:layout_constraintVertical_chainStyle="spread_inside" />

        <TextView
            android:id="@+id/supporting_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="16dp"
            android:text="Greyhound divisively hello coldly wonderfully marginally far upon excluding."
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:textColor="#DE000000"
            app:layout_constraintTop_toBottomOf="@+id/media_image"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </android.support.constraint.ConstraintLayout>

</android.support.v7.widget.CardView>

You can check out other card implementations via ConstraintLayout here. All of them were built in compliance with Material design guidelines.

like image 91
Eugene Brusov Avatar answered Jan 17 '23 00:01

Eugene Brusov


The easiest way would be to use PercentRelativeLayout as the parent ViewGroup. Then you can set the follow XML attributes on your ImageView

 app:layout_widthPercent="100%"
 app:layout_aspectRatio="178%"

Another option is to write your own custom ImageView and override onMeasure() to ensure that the view ends up with a 16:9 ratio. This answer shows you how to do that.

like image 41
James McCracken Avatar answered Jan 17 '23 01:01

James McCracken