156

I need to include a header graphic in all of my activities/views. The file with the header is called header.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent" 
  android:layout_height="wrap_content"
  android:background="#0000FF" 
  android:padding="0dip">

  <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/header"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="0dip"
    android:layout_marginTop="0dip"
    android:layout_marginBottom="0dip"
    android:padding="0dip"
    android:paddingTop="0dip"
    android:paddingBottom="0dip"
    android:layout_gravity="fill"
    android:background="#00FF00"
    />
</FrameLayout>

Note the android:background="#00FF00" (green), it's just visualisation purposes.

I include them into my views like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
  style="@style/white_background">

  <include layout="@layout/header" />
  (...)

So, when I actually try it out, the result looks like the left image, instead of what it should look like (right):

note the green border

(1) This - the orange - part is the image/ImageView in question
(2) The unloved green border. note: normally, the green area would be transparent - It's only green because I set the background.

Note the green border around the image at the top; It's part of the ImageView and I just can't figure out why it is there or how I can get rid of it. It set all paddings and margins to 0 (but the result is the same when I omit them). The image is a 480x64px jpeg* and I put it in res/drawable (not in one of the drawable-Xdpi though).

(* jpeg, because it seems I stumbled upon the old png gamma problem - at first I worked around the problem by making the green border the same orange as the picture, and the colors didn't match.)

I tried it on my htc desire/2.2/Build 2.33.163.1 and on the emulator. Also I described the problem to someone in #android-dev; She could reproduce the problem but had no explanation either. build target is 1.6.

update @tehgoose: this code yields the exact same top+bottom padded result.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
  style="@style/white_background">

  <!-- <include layout="@layout/header" />  -->

  <ImageView
    android:src="@drawable/header"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#00FF00"
    android:layout_weight="0"
    />

  <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="8dip"
    android:layout_weight="1">

    (... rest of the elements)

  </LinearLayout>
</LinearLayout>
Masoud Mokhtari
  • 2,390
  • 1
  • 17
  • 45
stefs
  • 18,341
  • 6
  • 40
  • 47
  • Negative margin and/or padding values may also work -`android:layout_margin="-10dp"`, `android:padding="-10dp"` – samus Nov 16 '18 at 21:22

8 Answers8

477

finally!

<ImageView
  (...)
  android:adjustViewBounds="true" />

the adjustViewbounds attribute did the trick:

Set this to true if you want the ImageView to adjust its bounds to preserve the aspect ratio of its drawable.

i stumbled upon it here. thanks for your help!

Community
  • 1
  • 1
stefs
  • 18,341
  • 6
  • 40
  • 47
  • 11
    I have the same problem, but this solution had no effect. – Marty Miller Aug 02 '12 at 19:51
  • 4
    Wow...without that attribute there was unwanted padding being added depending on the screen density, so it only was happening on some devices. It drove me nuts because the image looked fine on all the devices I own, then when I'd try it on a friend's device, it looked like crap. THANK YOU. – DiscDev Dec 14 '12 at 15:09
  • Thank gods I switch my first atempt from trying to solve bug to find something weard of android. I believe this problem started in some manufacturers changing stuff from android and then they have to put a property to solve it in next versions. – Ratata Tata May 31 '15 at 23:10
  • Sadly this doesn't work for lower apis, api 16 & 17 at the least. – luoser Jan 15 '16 at 23:22
  • @luoser - when i wrote this android 2.3 was cutting edge – stefs Jan 19 '16 at 11:55
  • Solved a major problem for me. As my minimum API is 17, works great. – Nagaraju Gajula Sep 27 '16 at 11:40
  • 1
    Wow this is exactly what I was looking for, I was scratching my head for a few hours, even went as far as trying to invalidate my layout and setting it's height/width to the image's. Such a simple solution that works perfectly without the need for scaleType. – CodyEngel Feb 12 '17 at 22:12
45
android:scaleType="fitXY"

It works for me.

shivtej
  • 633
  • 9
  • 18
fullmoon
  • 8,030
  • 5
  • 43
  • 58
  • 4
    `scaleType="fitXY"` does something different though: it changes the aspect ratio of the image, leading to distortion. this might be acceptable sometimes, e.g. for an abstract background image. – stefs Oct 24 '14 at 13:45
  • 1
    I controlled aspect ratio using android:width and android:height, and scaleType="fitXY" did fill the imageView for me with the desired aspect ratio, that was at least my experience. Thanks for your input. – fullmoon Oct 24 '14 at 18:40
  • It Works but Image is unpretty, unbalance, cropped – 최봉재 Apr 21 '16 at 07:04
  • 3
    Not exactly but android:scaleType="fitEnd" worked like magic. – TheLibrarian Mar 13 '17 at 09:49
  • I found a combination of `android:adjustViewBounds="true"` and `android:scaleType="fitXY"` was what I needed to align ImageViews in my layout. The images were off by a pixel or two (very small on a hi-res display) with just `adjustViewBounds`. Adding the `scaleType` seems to force a final scaling of the image after the view bounds are adjusted which forces the image to scale to the full size of the new bounds. – Jeff Lockhart Aug 27 '18 at 19:12
11

those extra padding is autogenerated since the android would try to get the original aspect ratio. please try below

   android:scaleType="fitCenter"
   android:adjustViewBounds="true"
   android:layout_height="wrap_content"
RileyManda
  • 2,536
  • 25
  • 30
MJ Montes
  • 3,234
  • 1
  • 19
  • 21
3

It has to do with the image aspect ratio. By default, the system keeps the original aspect ratio of the image source. Which in most cases does not exactly match the layout or dimensions specified in the layout. Therefore,

  1. Either change the size of the image to fit the specified layout, or
  2. Use android:scaleType to fit the image. For example, you can specify android:scaleType="fitXY"
Satan Pandeya
  • 3,747
  • 4
  • 27
  • 53
Nazar Merza
  • 3,365
  • 1
  • 19
  • 19
1

use this android:scaleType="fitXY" in imageview xml

Gaurav Pandit
  • 939
  • 1
  • 8
  • 13
0
android:layout_height="wrap_content"

You need to change it to "fill_parent"

You also might need to scale your image so it will be the right ratio to fill the framelayout it is in.

I don't understand why you need the frame layout there at all. Without it, your image would just fill the screen anyways.

EDIT: yes, sorry, the xml is the height for the imageview.

NotACleverMan
  • 12,107
  • 12
  • 47
  • 67
  • 1
    The only thing to add is that he need to set layout height of `ImageView`, it's not so evident in your answer :) – ernazm Apr 29 '11 at 10:00
  • i tried it without a surrounding layout too, doesn't change anything. also, the current image is just a placeholder - there will be additional elements soon (justifying the surrounding layout). i don't want the image to match the screen, i want it just there, at the top. – stefs Apr 29 '11 at 10:57
  • Double check to see if your image has blank space on the top and bottom. If not then try out scaling the imageview object using android:scaleType="". There should be one to suit what you're looking for. – NotACleverMan Apr 29 '11 at 12:58
0

May be you can give specific height to imageView say 50dp or 40dp and adjust image to make green border dissappear.

Eg: android:layout_height="40dp"

Uday
  • 5,933
  • 9
  • 44
  • 76
  • setting the layout_width="480px" and layout_height="64px" yields the result i want to, but pixels are not very practical. i honestly don't understand how that translates to dp. – stefs Apr 29 '11 at 11:25
  • You should use dp just as you would pixels. That's all they are; display independent pixels. but it works. – Uday Apr 29 '11 at 11:37
  • dp/dip means Density Independent Pixels; as far as i understand, it covers different densities, but (of course) not different screen sizes. all i want is the image to scale to 100% screen width and leave the height so proportions are kept. – stefs Apr 29 '11 at 11:50
-1

You need to provide shape around imageview to give a better look.

Here what i have used:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!--<gradient android:startColor="#FFFFFF" android:endColor="#969696"

    android:angle="270">
-->
<gradient android:startColor="#FFFFFF" android:endColor="#FFFFFF"

    android:angle="270">
</gradient>
    <stroke android:width="2dp" android:color="@color/graycolor" />
<corners android:radius="2dp" />
<padding android:left="5dp" android:top="5dp" android:right="5dp"
    android:bottom="5dp" />

Zoombie
  • 3,590
  • 5
  • 33
  • 40
  • 2
    whoa! i already worked with shapes (for tab backgrounds), but honestly, i don't understand how i should apply that here. – stefs Apr 29 '11 at 11:55
  • @Schnalle: make two shapes.xml file, and one selector.xml. apply image background as selector.xml file. In selector file provide two states for focused/selected and normal state. – Zoombie May 02 '11 at 07:50