79

My layout structure is like this

LinearLayout
    FrameLayout
       ImageView
       ImageView
    FrameLayout
    TextView
LinearLayout

I have set margin's for the two ImageView which are inside FrameLayout. But FrameLayout margins are discarded and it always set's the Image to top left corner. If i change from FrameLayout to LinearLayout the margin's work properly. How to handle this ?

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/inner1"
    >
        <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
        >

            <ImageView
             android:layout_width="24px" 
             android:layout_height="24px" 
             android:id="@+id/favicon"
             android:layout_marginLeft="50px"
             android:layout_marginTop="50px"
             android:layout_marginBottom="40px"
             android:layout_marginRight="70px"      

            />      
            <ImageView
             android:layout_width="52px" 
             android:layout_height="52px" 
             android:id="@+id/applefavicon" 
             android:layout_marginLeft="100px"
             android:layout_marginTop="100px"
             android:layout_marginBottom="100px"
             android:layout_marginRight="100px"              
            />

        </FrameLayout>  
            <TextView
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:id="@+id/title"                 
            android:layout_marginLeft="10px"        
            android:layout_marginTop="20px"
            android:textColor="#FFFFFF"  
            android:textSize = "15px"
            android:singleLine = "true"
            />

    </LinearLayout>
Vinoth
  • 5,687
  • 11
  • 44
  • 56

7 Answers7

225

I had the same issue myself and noticed that setting the layout_ margins does not work until you also set your ImageView's layout gravity i.e. android:layout_gravity="top" in the XML resource file, or from code: FrameLayout.LayoutParams.gravity = Gravity.TOP;.

Brent Faust
  • 9,103
  • 6
  • 53
  • 57
Andrei
  • 2,337
  • 1
  • 14
  • 4
  • 21
    It works, but it makes me feel dirty. I thought I had escaped the days of CSS hacks... – erlando Apr 30 '12 at 13:38
  • 1
    FrameLayout.LayoutParams.gravity does not have a gravity option in 2.3 – JPM Jul 13 '12 at 17:13
  • 2
    It seems to be fixed on 4.1 (probably before). Useful to know though – pablisco Nov 07 '12 at 18:04
  • fixed an issue I was having on the old kindle fire. Thanks! – DallinDyer Mar 04 '13 at 05:35
  • Can anyone explain why this works? This makes absolutely no sense why this fixes it. – Brandon Romano May 15 '13 at 17:45
  • 12
    To make it more clear why. The FrameLayout.onLayout() call contains this (in api v2.3.4 at least): `// for each child: final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int gravity = lp.gravity; if (gravity != -1) { // handle all margin related stuff ` So if gravity is -1, there will be no margin calculation. Gravity in FrameLayout.LayoutParams is defined by: `gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1); ` So if gravity is not set, there will be no margin calculation. – Miklos Jakab Sep 23 '13 at 14:59
  • May be helpfull: this is fix on 4.0.4 – Yura Shinkarev Sep 24 '13 at 20:57
  • In 4.2 works fine w/o any changes, but on 2.3 works only with the described fix. Thank you! – Nick Jan 28 '14 at 20:58
8

To make it more clear why. The FrameLayout.onLayout() call contains this (in api v2.3.4 at least):

    // for each child
    final LayoutParams lp = (LayoutParams) child.getLayoutParams();
    final int gravity = lp.gravity;
    if (gravity != -1) {
        // handle all margin related stuff

So if gravity is -1, there will be no margin calculation. And the thing is, gravity in FrameLayout.LayoutParams is defined by:

    gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1);

So if gravity is not set, there will be no margin calculation.

Miklos Jakab
  • 2,024
  • 1
  • 23
  • 31
7

add your xml this attribute and re run

android:layout_gravity="top"

everything is Ok!

and you dont set new layout params like this;

FrameLayout.LayoutParams llp = new FrameLayout.LayoutParams(WallpapersActivity.ScreenWidth/2, layH);

use like this:

FrameLayout.LayoutParams llp = (LayoutParams) myFrameLay.getLayoutParams();
llp.height = 100;
llp.width = 100;
myFrameLay.setLayoutParams(llp);
Savas Adar
  • 4,083
  • 3
  • 46
  • 54
1

Taken from the FrameLayout docs (link)

The size of the frame layout is the size of its largest child (plus padding), visible or not (if the FrameLayout's parent permits).

This seems to describe the fact that it'll strip margins out. Like boulder mentioned, you could try switching to padding as it can be used to produce a similar effect if done properly.

Out of curiosity, you mentioned that it does work fine when using a LinearLayout container, why the choice of FrameLayout?

Joey
  • 652
  • 1
  • 7
  • 15
0

try setCropToPadding(true) to ImageView ,this should be helped!

kidfolk
  • 11
  • 2
0

you have to set your ImageView's layout gravity top i.e. android:layout_gravity="top" in the XML resource file, or from code: FrameLayout.LayoutParams.gravity = Gravity.TOP

Komal Nikhare
  • 252
  • 1
  • 4
  • 9
0

Have you tried android:layout_gravity ? Try using android:padding in you ImageViews instead of android:layout_margin. AFAIK margins doesn't work properly on Frame layout. I even had to write custom layout for that purpose once. BTW, how do you want allign you ImageViews?

Dmitry Ryadnenko
  • 22,222
  • 4
  • 42
  • 56