Image View Not Scaling Between Different Devices

Viewed 238

My activity is structured as follows:

A recycle view that is populated with an adapter and a CardView Layout.

The CardView is comprised of a constraint layout that contains an image and two text boxes.

The Image is set to a drawable that is asynchronously loaded from a URL.

Here is some code:

Image Loading:

  try {
        InputStream is = (InputStream) new URL(url).getContent();
        Drawable d = Drawable.createFromStream(is, "src name");
        Bitmap bitmap = ((BitmapDrawable) d).getBitmap();
        Drawable temp = new BitmapDrawable(Bitmap.createScaledBitmap(bitmap, 300, 300, true));
        return temp;
      }
 catch (Exception e) {
        e.printStackTrace();
        return null;
      }

 This is called later in a different function where vh is the ViewHolder:
   vh.imageView.setImageDrawable(d);

CardView XML:

<?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="wrap_content">

    <androidx.cardview.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="4dp"
        app:cardElevation="4dp"
        app:cardUseCompatPadding="true"
        app:contentPadding="16dp" >

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/playlist_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/playlist_name"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.0"
                app:srcCompat="@mipmap/ic_launcher" />
etc...

RecyclerView XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PlaylistChoose">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/playlist_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="1dp"
        android:layout_marginEnd="1dp"
        android:clickable="true"
        android:focusable="auto"
        android:foreground="?attr/selectableItemBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:listitem="@layout/custom_playlist_view" >

    </androidx.recyclerview.widget.RecyclerView>

</androidx.constraintlayout.widget.ConstraintLayout>

Currently when I run this code on a Virtual Device the Image appears fine, However when I ran the app on a Galaxy S7 Edge the Images appeared extremely small. I then tried increasing the Height and Width in Drawable temp = new BitmapDrawable(Bitmap.createScaledBitmap(bitmap, 300, 300, true)); from 300 to about 1400 and the app then ran fine on the S7 But the virtual device now displayed the images as absurdly large. I'm a bit confused since the Image is inside a constraint layout that is set to wrap content and the content size is the same for both phones, So I don't understand why the actual size would differ... Thanks in advance! Any help is appreciated :)

Some pictures:

AVD 1400 : https://gyazo.com/1c4ab4ffb9266e191357dd3e0dcd2f5c

S7 1400: https://gyazo.com/fd87f094bf7f23933543369b206b794a

AVD 300: https://gyazo.com/d5c23c9372bc0c1838866452a24af06f

S7 300: https://gyazo.com/a9084b77d3efdd87cea9e53344c7b169

5 Answers

I'm a bit confused since the Image is inside a constraint layout that is set to wrap content and the content size is the same for both phones

The content may be the same for different phones but because different phone got different screen sizes while using wrap_content on your ImageView it won't look the same on all devices.

How to fix:

With ConstraintLayout you will want to do something like this:

Use this as your Image view:

  <ImageView
    android:id="@+id/imageView2"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintWidth_percent="0.25"
    app:layout_constraintHeight_percent="0.25"
    android:scaleType="fitXY"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.5"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:srcCompat="@drawable/your_image" />

Now, this will be exactly 25% in the width and height of its parent.

You can change the size of the image if you want, just change:

   app:layout_constraintWidth_percent="0.25"
   app:layout_constraintHeight_percent="0.25"

Try to add scaleType and adjustment of view bounds inside your ImageView

<ImageView
   android:id="@+id/playlist_image"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:scaleType="fitCenter"
   android:adjustViewBounds="true"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintEnd_toStartOf="@+id/playlist_name"
   app:layout_constraintHorizontal_bias="0.0"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintTop_toTopOf="parent"
   app:layout_constraintVertical_bias="0.0"
   app:srcCompat="@mipmap/ic_launcher" />

U can use

  android:scaleType="fitXY"
     <ImageView
            android:id="@+id/playlist_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/playlist_name"
            android:scaleType="fitXY"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"

            app:srcCompat="@mipmap/ic_launcher" />

Solved! It was due to a combination of @ADM's suggestion to use the glide library together with @Tamir Abutbul's Scale and Constraint Percent suggestion that my images now load correctly :)

XML:

<ImageView
                android:scaleType="fitXY"
                app:layout_constraintHeight_percent="1"
                app:layout_constraintWidth_percent="0.25"

                android:id="@+id/playlist_image"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/playlist_name"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.0"
                app:srcCompat="@mipmap/ic_launcher" />

Glide Code:

 Glide.with(context).load(url).into(vh.imageView);
Related