Barre d'état translucide/transparente + dispositif de coordination + barre D'outils + Fragment
j'ai la configuration suivante:
- j'utilise AppCompat
- MainActivity, qui est titulaire d'un fragment et a une barre d'outils, qui se cache lorsque le défilement vers le bas
-
Fragment
avecRecyclerView
- toutes les vues qui devraient s'adapter à l'écran ont la
android:fitsSystemWindows="true"
selon la disposition xml
le problème est, Je ne peux pas obtenir le statusbar transparent dans ce cas. Ce que je fais est le suivant:
- Créer de l'activité et de l'appel setContent
-
ensuite, j'essaie d'ajuster l'activité pour obtenir programmatiquement une barre d'outils translucide comme suit:
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public void themeNavAndStatusBar(Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; Window w = activity.getWindow(); w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); w.setFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); w.setFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); w.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent)); w.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent)); }
-
remplacer le paramètre dans l'activité (
@+id/frame_container
) par le fragment
le statusbar est de couleur unie dans ce cas, et le les vues ne sont pas établis en dessous... Pourquoi?
Ce que je veux
je veux une barre d'outils, qui est étalée de l'écran et se cache complètement tandis que le contenu sous cette barre d'outils devrait s'adapter à l'écran et être dessiné derrière la barre de navigation transparente.
Mises en page
Voici mon activité principale:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/clMain"
android:fitsSystemWindows="true"
android:background="?attr/main_background_color"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:fitsSystemWindows="true"
android:background="@null"
app:elevation="0dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="?actionBarThemeStyle"
app:popupTheme="?actionBarPopupThemeStyle"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/ivToolbarDataSource"
android:layout_gravity="center_vertical"
android:layout_marginRight="2dp"
android:layout_width="24dp"
android:layout_height="24dp" />
<TextView
android:id="@+id/tvToolbarTitle"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
android:theme="?actionBarThemeStyle"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/tvToolbarSubTitle"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle"
android:theme="?actionBarThemeStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<!-- BUG: /q/coordinatorlayout-appbarlayout-does-not-draw-toolbar-properly-37916/"fill_parent"
android:layout_height="1dp"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/frame_container"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="32dp"
android:src="@drawable/ic_local_offer_white_24dp"
app:backgroundTint="?attr/colorPrimary"
app:borderWidth="0dp"
app:fabSize="normal"
app:rippleColor="?attr/colorPrimaryDark"
app:layout_anchorGravity="bottom|right|end"
app:layout_behavior="com.test.classes.ScrollAwareFABBehavior"/>
</android.support.design.widget.CoordinatorLayout>
et voici mon fragment, sera placé dans l'activité principale:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/srlImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvImages"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:id="@+id/tvEmpty"
android:gravity="center"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
EDITION Captures d'écran
j'utilise un thème de base clair/sombre et le thème tout à la main (parce que l'utilisateur peut sélectionner n'importe quelle couleur comme primaire/couleur d'accent), alors ne vous inquiétez pas que la barre d'outils est blanc (c'est le thème couleur d'arrière-plan et la couleur primaire du thème par défaut). J'ai ajouté une bordure noire pour que vous puissiez voir où l'activité se termine...
- Première capture D'écran: montre la barre d'outils, rien n'est scrolled
- deuxième Screenshot: je viens de commencer à faire défiler => la barre d'outils devrait maintenant faire défiler
- troisième Screenshot: le contenu principal doit maintenant défiler sous la barre de navigation...
à la fin, je vais bien sûr rendre la barre d'outils et la barre de navigation semi transparente pour un meilleur effet visuel...
7 réponses
tl;dr Set android:fitsSystemWindows="false"
au moins jusqu'à la racine CoordinatorLayout
et jusqu'au contenant intérieur du fragment, @frame_container
.
cela pourrait ne pas être la solution finale (i.e. il pourrait y avoir d'autres fitsSystemWindows
à changer) alors dites-moi si vous avez des problèmes.
pourquoi
quand il s'agit de la barre de statut, je pense à fitsSystemWindows
comme ainsi:
-
fitsSystemWindows="false"
: dessine la vue normalement, sous la barre d'état en raison des drapeaux de fenêtre que vous avez mis. -
fitsSystemWindows="true"
: dessine la vue normalement, sous la barre d'état en raison des drapeaux de fenêtre que vous avez mis, mais ajoute un rembourrage supérieur de sorte que le contenu est dessiné sous la barre d'état et ils ne se chevauchent pas.
en fait, à mon avis, Le le blanc que vous voyez n'est pas la couleur de la barre d'état, mais plutôt votre fond CoordinatorLayout
. Cela est dû à fitsSystemWindows="true"
sur le coordinateur: il dessine l'arrière-plan à l'ensemble de la fenêtre, mais ajoute le rembourrage supérieur au contenu de sorte que les vues internes ne sont pas couverts par la barre de statut.
Ce n'est pas ce que vous voulez. Votre contenu intérieur doit être couvert par la barre de statut, et donc vous devez mettre fitsSystemWindows="false"
au coordinateur (pour qu'il ne s'applique pas le rembourrage supérieur) et probablement pour le contenu lui-même.
une fois que vous obtenez comment cela fonctionne, il est facile de déboguer et d'atteindre l'effet que vous recherchez . en fait, ce n'est pas le cas. Des années passent, mais je passe encore des heures à essayer de trouver la bonne combinaison fitsSystemWindows, parce que la plupart des vues (dans les bibliothèques de soutien au moins) outrepassent le comportement par défaut que j'ai indiqué ci-dessus, de façons qui ne sont généralement pas intuitives. Voir this post"" pour un petit guide sur la façon de l'utiliser.
modifiez vos styles.xml (v21) , ajouter le style suivant
<style name="AppTheme.Home" parent="AppTheme.Base">
<!-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
vous pouvez changer le thème parent selon votre goût, mais maintenant déclarez ce thème dans votre AndroidManifest.fichier xml pour une activité particulière comme ceci :
<activity
android:theme="@style/AppTheme.Home"
android:name=".HomeActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
cela permettra à votre contenu visible sous la barre d'action transparente.
utilisez maintenant ce qui suit pour aligner votre barre d'outils au-dessous de la barre D'État correctement, appelez ceci dans votre oncreate:
toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
obtenir la hauteur statusbar en utilisant ce qui suit:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
supprimer les éléments suivants des étiquettes de mise en page de votre coordonnateur:
android:fitsSystemWindows="true"
maintenant, afin de réduire votre barre d'outils ou de la Cacher, vous pouvez vous référer au tutoriel suivant:
http://antonioleiva.com/collapsing-toolbar-layout/
assurez-vous que vous utilisez la version suivante de la bibliothèque de soutien de conception, car elle est sans bogue:
compile 'com.android.support:design:23.1.0'
après avoir lu vos descriptions au sujet de votre question, j'ai pensé styles de Google Photos correspond à votre exigence.
OK, Il ya juste quelques conseils pour votre question. Après mon test, ça fonctionne.
- si vous voulez afficher du contenu derrière la barre d'état, vous devez ajouter
<item name="android:windowTranslucentStatus">true</item>
dans votre style lorsque le niveau de version Android est plus grand que 19 (à savoir KitKat ) - si vous voulez afficher du contenu derrière la barre de navigation, vous devez ajouter
<item name="android:windowTranslucentNavigation">true</item>
dans votre style lorsque le niveau de version Android est plus grand que 19 (à savoir KitKat ) - si vous voulez cacher
Toolbar
en douceur lorsque le contenu est déroulé et pour montrerToolbar
en douceur lorsque le contenu est déroulé, vous besoin d'ajouterapp:layout_collapseMode="parallax"
dans votre Les attributs deToolbar
basés sur vos codes actuels.Bien sûr, vous coordination des besoinsToolbar
avecCollapsingToolbarLayout
CoordinatorLayout
etAppBarLayout
.
comme certains utilisateurs l'ont dit, en réglant android:fitsSystemWindows="false"
, la disposition se chevauchait en dessous de statusbar
.
je l'ai résolu en mettant android:fitsSystemWindows="true"
et dans CoordinatorLayout
tag paramètre app:statusBarBackground="@android:color/transparent"
.
pour moi, la raison n'était pas qu'il n'a pas fonctionné en soi, mais que j'utilise la bibliothèque de tiroir de matériel de Mike Penz et cette bibliothèque utilise plein écran + offset + fond personnalisé derrière la barre d'outils donc j'ai dû résoudre le problème en respectant cette configuration spéciale...
je vais récompenser les points à mon avis la réponse la plus informative si...
j'ai eu le même problème et ma solution a été d'ajouter android: fitsSystemWindows= "true " à la DrawerLayout
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
....
</android.support.v4.widget.DrawerLayout>
j'ai eu des problèmes pertinents dépendent de android:fitsSystemWindows réglage. Une fois que la fausse: Des collations ont été tirées sous la barre de Navigation Une fois en vrai: La barre d'état n'avait aucun fond transparent
Solution était vraiment simple... Pour ajouter android:layout_marginBottom= "48dp".
just to add <android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
tools:context=".MapsActivity"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
android:layout_marginBottom="48dp">
barre de Navigation théorique devrait avoir la taille fixe "48dp", mais dans les versions futures potentiellement il peut changer (comme barre D'État obtenu plus mince en 1dp en Guimauve), je ne voudrais pas compter sur taille fixe. Mieux en plus obtenir et appliquer sur le temps d'exécution.
si vous utilisez Google Map comme moi, vous pouvez vouloir savoir la taille de la barre D'ActionBar/barre d'outils et la barre de navigation dans le temps d'exécution:
dans onCreate utiliser ce code:
final TypedArray styledAttributes = MapsActivity.this.getTheme().obtainStyledAttributes(
new int[]{android.R.attr.actionBarSize});
mToolbarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
// translucent bars code. Will not fire below Lollipop
// Ask NavigationBar Height
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.coordinatorLayout),
new OnApplyWindowInsetsListener() { // setContentView() must be fired already
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
statusBar = insets.getSystemWindowInsetTop(); // You may also need this value
mNavBarHeight = insets.getSystemWindowInsetBottom();
if (mMap != null)
mMap.setPadding(0, mToolbarHeight, 0, mNavBarHeight);
// else will be set in onMapReady()
SharedPreferences.Editor editor = mSharedPref.edit();
editor
.putInt(NAVBAR_HEIGHT_KEY, mNavBarHeight)
.commit(); // Save the results in flash memory and run the code just once on app first run instead of doing it every run
return insets;
}
}
);
et ce qui est important. Si vous avez des couches supplémentaires comme tiroir etc mettez-les encapsuler le niveau de coordination à l'intérieur plutôt qu'à l'extérieur comme autrement il fera d'autres vues à l'intérieur plus court par le marginBottom