51
votes

I need to display three same size images (200 X 100) side by side (no gaps) on top of the screen. They should occupy entire width of the screen and preserve aspect ratio. Is it possible to accomplish that using only layout xml file, or I need to use java code?
Solution shoud be resolution independant... Can anybody post a solution or link for this (or similar) problem? Thanks!

4
I am currently trying to solve the same problem! Did not find a solution yet :(. might work of we wrote our own ImageView that automatically adjusts its height? But would be nicer to use the original ImageView.Patrick Boos
Here is a simple magic formula that will solve the problem in some cases: stackoverflow.com/a/23777047/294884Fattie

4 Answers

145
votes

Got it working! But as I said above, you need to create your own class. But it is pretty small. I created it with the help of this Bob Lee's answer in this post: Android: How to stretch an image to the screen width while maintaining aspect ratio?

package com.yourpackage.widgets;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;

public class AspectRatioImageView extends ImageView {

    public AspectRatioImageView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = width * getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth();
        setMeasuredDimension(width, height);
    }
}

Now to use it in the XML:

<com.yourpackage.widgets.AspectRatioImageView 
    android:id="@+id/image"
    android:src="@drawable/yourdrawable" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true" 
    android:layout_centerHorizontal="true" 
    android:adjustViewBounds="true" />

Have fun!

=====================================

Found another way to do the same only in XML by using android:adjustViewBounds="true". Here an example:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ImageView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/image1" />

    <ImageView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/image2" />


    <ImageView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:adjustViewBounds="true"
        android:src="@drawable/image2" />

</LinearLayout>
30
votes

Only a minor upgrade to take into account what could possible go wrong: null Drawable or 0 width.

package com.yourpackage.yourapp;

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

public class AspectRatioImageView extends ImageView {

public AspectRatioImageView(Context context)
{
    super(context);
}

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

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    Drawable drawable = getDrawable();
    if (drawable != null)
    {
        int width =  MeasureSpec.getSize(widthMeasureSpec);
        int diw = drawable.getIntrinsicWidth();
        if (diw > 0)
        {
            int height = width * drawable.getIntrinsicHeight() / diw;
            setMeasuredDimension(width, height);
        }
        else
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    else
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
6
votes

Jake Wharton improves AspectRatioImageView class, you can set dominantMeasurement and aspectRatio via xml. You can find it in the link below.

https://gist.github.com/JakeWharton/2856179

1
votes

I don't know about XML layouts and the android API, but the math is simple; find the width of the screen and divide by three. That's the width of each image. Now multiply the width by the original image's ratio of Height to Width. That's the height of each image.

int imageWidth = screenWidth / 3;
float ratio = originalImage.Height / (float)originalImage.Width;
int imageHeight = (int)(imageWidth * ratio);