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>
Vinoth
fuente

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;.

Andrei
fuente
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.

Miklos Jakab
fuente
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);
Savas Adar
fuente
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?

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

Dmitry Ryadnenko
fuente
no hay peso en un diseño de marco
njzk2
0

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

niños
fuente
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

Komal Nikhare
fuente