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>
Vinoth
źródło

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

Andrei
źródło
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.

Miklos Jakab
źródło
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);
Savas Adar
źródło
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?

Joey
źródło
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?

Dmitry Ryadnenko
źródło
nie ma wagi w framelayout
njzk2
0

spróbuj setCropToPadding (true) do ImageView, powinno to pomóc!

dzieciak
źródło
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

Komal Nikhare
źródło