0

Please look at this code fragment:

 <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:paddingBottom="35dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:paddingTop="10dp" >

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

        <ImageButton
            android:id="@+id/imageButton2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:paddingRight="5dp"
            android:scaleType="fitXY"
            android:src="@drawable/1" />

        <ImageButton
            android:id="@+id/imageButton3"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:paddingLeft="5dp"
            android:scaleType="fitXY"
            android:src="@drawable/2" />

        </LinearLayout>

    </LinearLayout>

I'm using this code in my Android app, based mainly on images. I have a problem with proper scaling. When I'm using scaleType="fitXY" (code above), everything on all dimensions looks fine, but not images' height. Width is properly stretched, but height not. I tried to use centerInside which doesn't stretch my images and keeps ratio okay. But then there's a problem with images' size - they're just too small on some devices. My question is - how to make an image-based app look the same (or very close) on all devices?

Samples:

https://i.stack.imgur.com/cjS5f.jpg width and height ok, but margins are messed up, fitCenter https://i.stack.imgur.com/4BUTr.jpg width is okay - but height not, fitXY

JaKoZo
  • 314
  • 2
  • 14
  • By keeping width = fillparent and height = wrapcontent, I guess you are trying to set up a banner. You see, with the fragmentation in Android, there is a really wide range of device dimensions to look after. The best way is to have separate images in your drawable folder for standard dimensions- The LDPI, MDPI, HDI and XHDPI. You will need to design images for these standards. – Parth Kapoor Jun 03 '14 at 11:44

3 Answers3

0

try replacing

android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scaleType="fitXY"

by

android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:scaleType="centerInside"

Since you seem to be trying to fill the screen horizontally, this would stretch the images across the screen as much as possible without distorting them

If you have a sort of background which you can crop and just want to fit horizontally try

android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:scaleType="center"
Rijul Gupta
  • 1,045
  • 13
  • 20
0

If you want to preserve the height/width ratio of the original image you can do it at run-time. Since you want for your ImageButton android:layout_width="fill_parent" android:layout_height="wrap_content" you can adapt the following code:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;  // just compute size, don't create bitmap
BitmapFactory.decodeStream(stream, null, options); // stream is the InputStream representing the image you want to display
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
imageViewWidth = imageView.getWidth(); // imageView is the View container for the image you want to display
imageViewHeight = imageView.getHeight();
// Compute the sample size
double sampleSize = computePowerOfTwoInSampleSize(options, imageViewWidth, imageViewHeight);
if(sampleSize<1) { 
    options.inSampleSize = 1; 
}
else { 
    options.inSampleSize = (int) sampleSize; 
}
options.inJustDecodeBounds = false; // compute size and create bitmap  
bitmap = BitmapFactory.decodeStream(stream, null, options);
imageView.setImageBitmap(bitmap);
try { 
    stream.close(); 
} 
catch (IOException e) { 
    e.printStackTrace(); 
}

where the method computePowerOfTwoInSampleSize is something like this (take into consideration that resizing to power of 2 is more efficient compared to other values):

private double computePowerOfTwoInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    int height = options.outHeight;
    int width = options.outWidth;
    double inSampleSize = 1;        
    // compute the up-sample coefficient (power of 2)
    if(height < reqHeight && width < reqWidth) {
        while(height < reqHeight && width < reqWidth) {
            height = height*2;
            width = width*2;
            if(height < reqHeight && width < reqWidth) {
                inSampleSize = inSampleSize/2;
            }
        }
    }
    // compute the down-sample coefficient
    else {
        while(height > reqHeight || width > reqWidth) { 
            // Calculate ratios of height and width to requested height and width (power of 2)
            height = Math.round((float)height/2);
            width = Math.round((float)width/2); 
            inSampleSize = inSampleSize*2;
        }
    }
    return inSampleSize;
}
bardi
  • 373
  • 5
  • 17
  • Can you give a sample how to use this code to some images ? – JaKoZo Jun 03 '14 at 15:41
  • You can convert bitmap to [byte stream](http://stackoverflow.com/questions/4989182/converting-java-bitmap-to-byte-array) and pass the stream to the `BitmapFactory.decodeStream(stream, null, options)`, then follow the comments in the code ;) – bardi Jun 03 '14 at 15:58
0

You should set it scaleType as Matrix and scale it to the closest side(top and bottom or left and right) keeping the aspect ratio.

user1488918
  • 140
  • 1
  • 7