Margines FrameLayout nie działa


79

Moja struktura układu jest taka

LinearLayout
    FrameLayout
       ImageView
       ImageView
    FrameLayout
    TextView
LinearLayout

Ustawiłem marginesy dla dwóch ImageView, które są wewnątrz FrameLayout. Ale marginesy FrameLayout są odrzucane i zawsze ustawia obraz w lewym górnym rogu. Jeśli zmienię FrameLayout na LinearLayout, marginesy działają poprawnie. Jak sobie z tym poradzić?

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

Odpowiedzi:


221

Miałem ten sam problem się i zauważył, że ustawienie layout_marginesów nie działa dopóki również ustawić ImageView za układ grawitacyjny IE android:layout_gravity="top"w pliku XML zasobów lub z kodu: FrameLayout.LayoutParams.gravity = Gravity.TOP;.


21
Działa, ale czuję się brudny. Myślałem, że uciekłem od czasów hacków CSS ...
erlando,

1
FrameLayout.LayoutParams.gravity nie ma opcji grawitacji w wersji 2.3
JPM

2
Wydaje się, że naprawiono to w 4.1 (prawdopodobnie wcześniej).
Warto

naprawiono problem, który miałem na starym ogniu rozpalającym. Dzięki!
DallinDyer

12
Aby było jaśniej, dlaczego. Wywołanie FrameLayout.onLayout () zawiera to (przynajmniej w api v2.3.4): // for each child: final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int gravity = lp.gravity; if (gravity != -1) { // handle all margin related stuff Więc jeśli grawitacja wynosi -1, nie będzie obliczania marginesu. Grawitacja w FrameLayout.LayoutParams jest zdefiniowana przez: gravity = a.getInt(com.android.internal.R.styleable.FrameLayout_Layout_layout_gravity, -1); Więc jeśli grawitacja nie jest ustawiona, nie będzie obliczania marginesu.
Miklos Jakab

8

Żeby było jaśniej, dlaczego. Wywołanie FrameLayout.onLayout () zawiera (przynajmniej w api v2.3.4):

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

Więc jeśli grawitacja wynosi -1, nie będzie obliczania marginesu. Rzecz w tym, że grawitacja w FrameLayout.LayoutParams jest definiowana przez:

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

Więc jeśli grawitacja nie zostanie ustawiona, nie będzie obliczania marginesu.


7

dodaj swój xml ten atrybut i uruchom ponownie

android: layout_gravity = "top"

wszystko w porządku!

i nie ustawiasz nowych parametrów układu w ten sposób;

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

użyj w ten sposób:

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

1
Więc jeśli nie masz LayoutParams, nastąpi awaria z drugą metodą.
Léon Pelletier

możesz to sprawdzić za pomocą if == null control.
Savas Adar

To rozwiązuje mój problem z margin_top na Androidzie 10.
Pedro Paulo Amorim,

1

Zaczerpnięte z dokumentacji FrameLayout ( link )

Rozmiar układu ramki to rozmiar największego elementu podrzędnego (plus wypełnienie), widocznego lub nie (jeśli rodzic FrameLayout na to pozwala).

Wydaje się, że opisuje to fakt, że spowoduje to usunięcie marginesów. Jak wspomniano w boulder, możesz spróbować przełączyć się na padding, ponieważ można go użyć do uzyskania podobnego efektu, jeśli zostanie wykonany prawidłowo.

Z ciekawości wspomniałeś, że działa dobrze, gdy używasz LinearLayoutkontenera, dlaczego wybór FrameLayout?


0

Czy próbowałeś android: layout_gravity? Spróbuj użyć android: padding w tobie ImageViews zamiast android: layout_margin. Marginesy AFAIK nie działają poprawnie w układzie ramki. Kiedyś musiałem nawet napisać niestandardowy układ do tego celu. A tak przy okazji, w jaki sposób chcesz połączyć ImageViews?


nie ma wagi w framelayout
njzk2


0

musisz ustawić top grawitacji układu ImageView, tj. android: layout_gravity = "top" w pliku zasobów XML lub z kodu: FrameLayout.LayoutParams.gravity = Gravity.TOP

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.