El margen de FrameLayout no funciona


79

Mi estructura de diseño es así

LinearLayout
    FrameLayout
       ImageView
       ImageView
    FrameLayout
    TextView
LinearLayout

He establecido márgenes para los dos ImageView que están dentro de FrameLayout. Pero los márgenes de FrameLayout se descartan y siempre establece la Imagen en la esquina superior izquierda. Si cambio de FrameLayout a LinearLayout, el margen funciona correctamente. ¿Cómo manejar esto?

<?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>

Respuestas:


221

Yo tenía el mismo problema a mí mismo y di cuenta de que el establecimiento de los layout_márgenes no funciona hasta que también configura la gravedad es decir, el diseño de su ImageView android:layout_gravity="top"en el archivo de recursos XML, o de código: FrameLayout.LayoutParams.gravity = Gravity.TOP;.


21
Funciona, pero me hace sentir sucio. Pensé que había escapado de los días de los hacks de CSS ...
erlando

1
FrameLayout.LayoutParams.gravity no tiene una opción de gravedad en 2.3
JPM

2
Parece estar arreglado en 4.1 (probablemente antes). Sin embargo, es útil saberlo
pablisco

Se solucionó un problema que estaba teniendo en el antiguo Kindle Fire. ¡Gracias!
DallinDyer

12
Para dejar más claro por qué. La llamada FrameLayout.onLayout () contiene esto (en api v2.3.4 al menos): // for each child: final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int gravity = lp.gravity; if (gravity != -1) { // handle all margin related stuff Entonces, si la gravedad es -1, no habrá cálculo de margen. La gravedad en FrameLayout.LayoutParams se define mediante: gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1); Entonces, si no se establece la gravedad, no habrá cálculo de margen.
Miklos Jakab

8

Para dejar más claro por qué. La llamada FrameLayout.onLayout () contiene esto (en api v2.3.4 al menos):

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

Entonces, si la gravedad es -1, no habrá cálculo de margen. Y la cuestión es que la gravedad en FrameLayout.LayoutParams se define por:

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

Entonces, si no se establece la gravedad, no habrá cálculo de margen.


7

agregue su xml este atributo y vuelva a ejecutar

android: layout_gravity = "top"

¡todo está bien!

y no establece nuevos parámetros de diseño como este;

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

usar así:

FrameLayout.LayoutParams llp = (LayoutParams) myFrameLay.getLayoutParams();
llp.height = 100;
llp.width = 100;
myFrameLay.setLayoutParams(llp);

1
Entonces, si no tiene LayoutParams, se bloqueará con el segundo método.
Léon Pelletier

puedes comprobarlo con if == null control.
Savas Adar

Esto resuelve mi problema con margin_top en Android 10.
Pedro Paulo Amorim

1

Tomado de los documentos de FrameLayout ( enlace )

El tamaño del diseño del marco es el tamaño de su hijo más grande (más el relleno), visible o no (si el padre del FrameLayout lo permite).

Esto parece describir el hecho de que eliminará los márgenes. Como se mencionó en Boulder, puede intentar cambiar a relleno, ya que puede usarse para producir un efecto similar si se hace correctamente.

Por curiosidad, mencionaste que funciona bien cuando se usa un LinearLayoutcontenedor, ¿por qué elegir FrameLayout?


0

¿Has probado android: layout_gravity? Intente usar android: padding en sus ImageViews en lugar de android: layout_margin. Los márgenes AFAIK no funcionan correctamente en el diseño de cuadros. Incluso tuve que escribir un diseño personalizado para ese propósito una vez. Por cierto, ¿cómo quieres asignar tus ImageViews?


no hay peso en un diseño de marco
njzk2

0

intente setCropToPadding (true) en ImageView, ¡esto debería ser ayudado!


0

tienes que configurar la parte superior de gravedad del diseño de ImageView, es decir, android: layout_gravity = "top" en el archivo de recursos XML, o desde el código: FrameLayout.LayoutParams.gravity = Gravity.TOP

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.