2016-09-03 4 views
10

Ich habe SingleFramgnetActivity, deren Zweck nur darin besteht, Fragmente darin zu halten und zu ersetzen.Android fitsSystemWindows funktioniert nicht beim Ersetzen von Fragmenten

Layout wie folgt aussieht:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center_horizontal" 
    android:orientation="vertical" 
    tools:context=".SingleFragmentActivity" 
    > 

    <include layout="@layout/toolbar"/> 

    <FrameLayout 
     android:id="@+id/content" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     /> 
</LinearLayout> 

ich die Fragments innerhalb des FrameLayout ersetzen. Wenn ich die auf Fragment Layout auf True setzt, reagiert es nicht. Eigentlich funktioniert es nur, wenn Activity erstellt wird, aber sobald ich die Fragment innerhalb der FrameLayout ersetzen, wird der fitsSystemWindows Parameter ignoriert und das Layout ist unter der Statusleiste und Navigationsleiste.

Ich fand einige solution mit benutzerdefinierten FrameLayout, die veraltete Methoden verwendet, aber aus irgendeinem Grund funktioniert es nicht für mich (das gleiche Ergebnis wie mit normalen FrameLayout) und ich mag auch nicht die Idee, veraltete Methoden zu verwenden.

+0

sind Sie sich bewusst, was fitsSystemWindow tut? –

+0

Ich hoffe, dass ich es richtig verstehe, im Grunde, wenn es auf wahr gesetzt ist, sollten die Ansicht und alle ihre Kinder nicht unter den Systemfenstern als Statusleiste oder Navigationsleiste angezeigt werden. Wenn es auf false gesetzt ist, sollte es unter den Systemfenstern angezeigt werden. Im Grunde kann ich einstellen, dass ich das gesamte Fragment-Layout zwischen Statusleiste und Navigationsleiste (fitsSystemWindow = true) und Hintergrundbild unter der Statusleiste und Navigationsleiste rendern möchte (fitsSystemWindow = false). Ich kann es genau so machen, wie ich es will, bis ich die Fragmente nicht ersetze. – Sandak

+1

Ich hatte das gleiche Problem. Am Ende habe ich ein FrameLayout erstellt, das die Fenstereinfügungen speichert und sie an neue Kinder weiterleitet. Ich habe den Code in einen [Github gist] (https://gist.github.com/PaeP3nguin/4e41f7e76be452fe2f78d3c534fb8dd1) eingefügt. Lass es mich wissen, wenn das für dich funktioniert! – paep3nguin

Antwort

3

Ihre FrameLayout ist Fenstergrößen nicht bewusst, weil es Elternteil ist - LinearLayout hat ihn nicht gesendet. Als Abhilfe können Sie LinearLayout und Pass-Einsätze für Kinder auf eigene Unterklasse:

@TargetApi(Build.VERSION_CODES.KITKAT_WATCH) 
@Override 
public WindowInsets onApplyWindowInsets(WindowInsets insets) { 
    int childCount = getChildCount(); 
    for (int index = 0; index < childCount; index++) 
     getChildAt(index).dispatchApplyWindowInsets(insets); // let children know about WindowInsets 

    return insets; 
} 

Sie einen Blick auf my this Antwort haben kann, die detailliert erklärt, wie das funktioniert, und auch, wie ViewCompat.setOnApplyWindowInsetsListener API zu verwenden.

+1

Verwenden Sie immer 'ViewCompat.setOnApplyWindowInsetsListener', wenn Sie die API unter 20 unterstützen, weil http://StackOverflow.com/Questions/35028395/android-view-windowinsets-classnotFoundexception/42380189#42380189. –

+0

@azizbekian Ihre Erklärung ist nützlich, aber es hilft mir immer noch nicht, das Problem mit veränderten Fragmenten zu lösen. fitSystemWindows arbeitet im Fragmentlayout, wenn das Fragment zum ersten Mal geöffnet wird, wird aber ignoriert, wenn das Fragment ein anderes Fragment ersetzt. Ich spreche über FitSystemWindows auf Nicht-Root-Ansicht-zweite Ebene. Auf der ersten Ebene funktioniert es. Alle Ansichten in der Hierarchie in Aktivität und Fragmenten sind Koordinator-Layouts oder implementieren die Methode aus Ihrer Antwort. – lobzik

+0

@lobzik, Überprüfen Sie Ihre Ansichtshierarchie und finden Sie die übergeordnete Ansicht, die keine Einsätze an die untergeordneten Elemente verteilt. Sie können 'ViewCompat.setOnApplyWindowInsetsListener' verwenden und prüfen, welche' ViewGroup' genau 0 als Inset-Größe zurückgibt. – azizbekian

0

Sie können auch eine benutzerdefinierte WindowInsetsFrameLayout und verwenden Sie bauen eine OnHierarchyChangedListener wieder die Einsätze Anwendung zu beantragen:

public WindowInsetsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 

    // Look for replaced fragments and apply the insets again. 
    setOnHierarchyChangeListener(new OnHierarchyChangeListener() { 
     @Override 
     public void onChildViewAdded(View parent, View child) { 
      requestApplyInsets(); 
     } 

     @Override 
     public void onChildViewRemoved(View parent, View child) { 

     } 
    }); 
} 

Schauen Sie sich diese ausführliche Antwort: https://stackoverflow.com/a/47349880/3979479

Verwandte Themen