3

I'm writing an Android app with minSdkVersion = 15 (testing on 19). I would like to have an overlay with a small phone picture in the middle. I added the drawable (xml) resource ic_smartphone_black_24dp from the standard Android's pictures and created an ImageView for the overlay like this:

<ImageView
    android:id="@+id/overlay"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:alpha="1."
    android:background="@drawable/overlay_full"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

This renders the overlay, but the smartphone picture is stretched to the whole ImageView: screenshot

I tried to scale the phone's picture in various ways (reading this, that and many others), but none of it worked. In particular I tried:

  • adding vectorDrawables.useSupportLibrary = true to gradle.build
  • adding
static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

to the Activity

  • changing the ImageView to android.support.v7.widget.AppCompatImageView (and setting the background in java code and not in xml)
  • passing wrap_content instead of 0dp as layout_width/height (and removing the constraints)
  • setting the size in the overlay_full:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/overlay_background">
        <size
            android:width="152dp"
            android:height="152dp"/>
    </item>
    <item android:drawable="@drawable/ic_smartphone_black_24dp"
        android:left="30dp"
        android:top="30dp"
        android:right="30dp"
        android:bottom="30dp"
        android:gravity="center"
        android:scaleType="center"
        android:width="30dp"
        android:height="30dp">
        <size
            android:width="30dp"
            android:height="30dp"/>
    </item>
</layer-list>

The code works as expected in API 28 where I also tested. Any idea how to do this scaling in earlier API versions?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
sygi
  • 4,557
  • 2
  • 32
  • 54

1 Answers1

1

You could try something like this:

<ImageView
    android:id="@+id/overlay"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:scaleType="center"
    android:background="@drawable/just_the_background"
    app:srcCompat="@drawable/ic_smartphone_black_24dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

Also, you don't need to use AppCompat views directly in layouts, just let the library handle this for you (they are replaced automatically at build time). You only need to use them if you're extending them to add custom functionality.

Philio
  • 3,675
  • 1
  • 23
  • 33
  • Thank you! That works, however I'm concerned about how it will scale to different screen sizes: won't the image be 24dp now no matter the screen size? (and thus will scale differently than just_the_background)? – sygi Mar 30 '19 at 15:09
  • Yes it would always be 24dp (or whatever you set the height/width to in the vector's XML). Could you describe how you want it to scale? – Philio Mar 30 '19 at 15:20
  • To scale the image based on the screen size, one option would be to use `android:scaleType="fitCenter"` and you could add padding to create a border. – Philio Mar 30 '19 at 15:33
  • My final goal is to have a background with some static elements and foreground with an animated phone. I'm afraid that if I add padding to the border, Android will automatically scale my image down when it'll be moving due to animation to fit it all (including padding) on the screen. On the other hand, if it's always 24dp, it will likely intersect with the static elements of the background whenever background is scaled to a different size. I'd like the background and foreground scale together and the phone to not fill the whole screen (neither physically or through padding) I think. WDYT? – sygi Mar 30 '19 at 15:49
  • It sounds like at that point it might be worth using multiple views within the `ConstraintLayout` and constrain them in such a way that they don't overlap, e.g. use chains or just position them relative to each other. If you can add an image to demonstrate what you're trying to achieve (e.g. a wireframe) it might be easier to offer a more complete answer. – Philio Mar 30 '19 at 21:27
  • Actually, I end up doing what you suggested (assuming no scaling). Thanks for your help and sorry for complaining :P – sygi Mar 30 '19 at 23:19