Android – Is it possible to prevent a background from getting SMALLER, but allow it to resize itself to get bigger?

I have this image:

Image

This is how its appearing on small devices:

Image

It looks kinda squishy. I’d like it that it DOESN’T resize it, displays it as it is, not showing the part of the image that doesn’t fit in the screen. Like this

Image

If you haven’t noticed, the phone’s screen in the pic above has a background which wan’t resized, it just took as much as fits the screen from the center image. It cuts the parts that don’t fit the screen and takes as much as it needs from the center.

When I use it on a tablet, it works perfectly, since the tablets have a big screen size:

enter image description here

How can I do this?

Currently, this is my code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout   
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/activity_sign_in"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.alibdeir.irecipify.SignInActivity"
  android:background="@drawable/food_wallpaper">

</android.support.constraint.ConstraintLayout>

Answer

I fixed it by making a ScaleImageView java class:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.RelativeLayout;

/**
 * Created by Ab-Me on 25-Aug-16.
 * This is the imageView for the background image
 */
@SuppressWarnings("all")
public class ScaleImageView extends ImageView {
    private ImageChangeListener imageChangeListener;
    private boolean scaleToWidth = false; // this flag determines if should measure height manually dependent of width

    public ScaleImageView(Context context) {
        super(context);
        init();
    }

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

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

    private void init() {
        this.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        if (imageChangeListener != null)
            imageChangeListener.changed((bm == null));
    }

    @Override
    public void setImageDrawable(Drawable d) {
        super.setImageDrawable(d);
        if (imageChangeListener != null)
            imageChangeListener.changed((d == null));
    }

    @Override
    public void setImageResource(int id) {
        super.setImageResource(id);
    }

    public interface ImageChangeListener {
        // a callback for when a change has been made to this imageView
        void changed(boolean isEmpty);
    }

    public ImageChangeListener getImageChangeListener() {
        return imageChangeListener;
    }

    public void setImageChangeListener(ImageChangeListener imageChangeListener) {
        this.imageChangeListener = imageChangeListener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        /**
         * if both width and height are set scale width first. modify in future if necessary
         */

        if (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST) {
            scaleToWidth = true;
        } else if (heightMode == MeasureSpec.EXACTLY || heightMode == MeasureSpec.AT_MOST) {
            scaleToWidth = false;
        } else
            throw new IllegalStateException("width or height needs to be set to match_parent or a specific dimension");

        if (getDrawable() == null || getDrawable().getIntrinsicWidth() == 0) {
            // nothing to measure
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        } else {
            if (scaleToWidth) {
                int iw = this.getDrawable().getIntrinsicWidth();
                int ih = this.getDrawable().getIntrinsicHeight();
                int heightC = width * ih / iw;
                if (height > 0)
                    if (heightC > height) {
                        // dont let hegiht be greater then set max
                        heightC = height;
                        width = heightC * iw / ih;
                    }

                this.setScaleType(ScaleType.CENTER_CROP);
                setMeasuredDimension(width, heightC);

            } else {
                // need to scale to height instead
                int marg = 0;
                if (getParent() != null) {
                    if (getParent().getParent() != null) {
                        marg += ((RelativeLayout) getParent().getParent()).getPaddingTop();
                        marg += ((RelativeLayout) getParent().getParent()).getPaddingBottom();
                    }
                }

                int iw = this.getDrawable().getIntrinsicWidth();
                int ih = this.getDrawable().getIntrinsicHeight();

                width = height * iw / ih;
                height -= marg;
                setMeasuredDimension(width, height);
            }

        }
    }

}

(It’s OK to simply copy and paste this class, it’s the same as using a Library)

Then in your XML (Your parent must be RelativeLayout):

<!-- This is the UI of the class you created -->
<com.your.package.name.ScaleImageView 
    android:id="@+id/background"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:adjustViewBounds="true"
    android:scaleType="centerCrop"
    android:src="@drawable/food_wallpaper"
    tools:ignore="ContentDescription" />

android:scaleType="centerCrop" makes the image crop to the center. The alignX attributes make the image full screen.

Source: stackoverflow
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .