web-dev-qa-db-fra.com

Pré-sucette de la barre d'outils Appcompat v21

Tout d’abord, je sais que cette question a déjà été posée, mais qu’aucune réponse n’a été donnée. J'espère que quelqu'un pourra me donner une réponse.

Dans mon application, j'utilise la barre d'outils d'Appcompat_v7 (API 21). Ceci est mon code:

<Android.support.v7.widget.Toolbar
    style="@style/DarkActionbarStyle"
    Android:id="@+id/toolBar"
    Android:layout_width="match_parent"
    Android:layout_height="@dimen/actionbar_height" />

Et c'est le style de barre d'outils que j'utilise:

<style name="DarkActionbarStyle" parent="@style/Widget.AppCompat.Toolbar">
    <item name="Android:background">?attr/colorPrimary</item>
    <item name="titleTextAppearance">@style/ActionBarTitle</item>
    <item name="Android:elevation">2dp</item>
    <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
    <item name="theme">@style/ThemeActionBarDark</item>
</style>

<style name="ThemeActionBarDark" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    <item name="actionBarItemBackground">@drawable/btn_dark_orange</item>
    <item name="selectableItemBackground">@drawable/btn_dark_orange</item>
</style>

Le problème, c'est que l'altitude ne fonctionne pas avant Lollipop. Donc ma question est: Est-il possible d'avoir une ombre sous la barre d'outils sur les appareils pré-Lollipop?

43

Cela a très bien fonctionné pour moi:

<Android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@color/primary"
    card_view:cardElevation="4dp"
    card_view:cardCornerRadius="0dp">

    <Android.support.v7.widget.Toolbar
        Android:id="@+id/toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="@color/primary"
        Android:minHeight="?attr/actionBarSize" />

</Android.support.v7.widget.CardView>
75
Islam A. Hassan

L'utilisation du conteneur CardView pour la barre d'outils est une mauvaise idée.

CardView est lourd, surtout pour les appareils bas de gamme.

La meilleure solution consiste à placer une vue Ombre dégradée sous la barre d'outils. La vue fantôme doit être un enfant direct de la disposition du coordinateur. c'est à dire. La barre d’application contenant la barre d’outils et la vue fantôme doit être un frère ou une soeur.

Ajoutez ce composant de vue à votre mise en page.

 <View
    Android:id="@+id/gradientShadow"
    Android:layout_width="match_parent"
    Android:layout_height="5dp"
    Android:background="@drawable/toolbar_shadow"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    app:layout_collapseMode="pin"/>

Le drawable toolbar_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
   Android:shape="rectangle">
<gradient
    Android:angle="90"
    Android:endColor="#33333333"
    Android:startColor="@Android:color/transparent"/>
</shape>

Cela résoudra les problèmes des appareils pré-Lollipop. Mais nous ne voulons pas de cette ombre dans les appareils Lollipop et au-dessus, alors donnez de la visibilité aux appareils disparus avec Lollipop et au-dessus.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        findViewById(R.id.gradientShadow).setVisibility(View.GONE);
}

Terminé.

16
shijin

Vous pouvez rajouter l’ombre (élévation) en utilisant un FrameLayout avec foreground="?android:windowContentOverlay". L'attribut d'altitude n'est pas pris en charge avant Lollipop. Donc, si vous utilisez FrameLayout comme fragment de conteneur, ajoutez-y simplement un attribut de premier plan.

12
Sniper

Comme j'ai eu des problèmes avec la méthode du widget CardView, j'ai utilisé la méthode FrameLayout mentionnée par @Sniper; cela fonctionne parfaitement!

Je voulais juste partager l'extrait de code que vous devrez utiliser. Il suffit de placer ceci directement sous la barre d'outils à l'endroit où commence votre contenu principal:

<FrameLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:foreground="?android:windowContentOverlay">

Et n'oubliez pas de fermer avec:

</FrameLayout>
7
MegaCookie

Il est possible d'avoir de vraies ombres - animées et générées. La méthode utilisée par Lollipop est disponible depuis Froyo. L'accélération matérielle utilisée pour la génération des ombres est disponible depuis Honeycomb, je suppose. Voici comment cela fonctionne:

  • dessinez votre vue sur un bitmap hors écran avec LightingColorFilter défini sur 0,0
  • rendre flou la forme noire (bitmap hors écran) en utilisant la classe ScriptIntrinsicBlur et la valeur d'élévation en tant que rayon
  • dessiner le bitmap sous la vue

Cela nécessite l'ajout d'attributs d'élévation personnalisés, de vues personnalisées capables de restituer les ombres, ainsi que l'utilisation d'un script de rendu et de la bibliothèque de compatibilité (pour les anciens périphériques). Je ne vais pas entrer dans les détails, car il y en a beaucoup, notamment des problèmes de compilation et d'optimisation mineures des performances. Mais c'est possible.

Pourquoi n'y a-t-il pas d'ombres dans la bibliothèque de support officielle?

  • il faudrait modifier le cadre de l'interface utilisateur, car il est impossible de dessiner librement des limites de vue extérieures
  • une animation fluide nécessite un assez bon GPU

Voir:

6
Zielony

J'utilise ceci réponse :

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:orientation="vertical">

<Android.support.v7.widget.Toolbar xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@color/orange"
    Android:titleTextAppearance="@color/White"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

    <View
        Android:layout_width="match_parent"
        Android:layout_height="5dp"
        Android:background="@drawable/toolbar_shadow" />
</LinearLayout>

toolbar_shadow.xml :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <gradient
        Android:startColor="#3f3f3f"
        Android:endColor="@Android:color/transparent"
        Android:angle="270" />
</shape>
5
Leebeedev

Vous ne pouvez pas utiliser l'attribut d'altitude avant l'API 21 (Android Lollipop). Vous pouvez cependant ajouter l'ombre par programmation, par exemple en utilisant une vue personnalisée placée sous le Toolbar.

Par exemple:

<ImageView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/toolbar"
        Android:background="@drawable/shadow"/>

Où l'ombre est dessinable avec un dégradé noir.

4
Alessandro Roaro

Pour afficher une ombre sous votre barre d’outils, utilisez AppBarLayout disponible dans Google Android Design Support Library. Voici un exemple d'utilisation.

<Android.support.design.widget.AppBarLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content">
   <Android.support.v7.widget.Toolbar
            Android:layout_height="?attr/actionBarSize"
            Android:layout_width="match_parent"/>
     </Android.support.design.widget.AppBarLayout>

Pour utiliser Google Android Design Support Library, saisissez ce qui suit dans votre fichier build.gradle:

 compile 'com.Android.support:design:22.2.0'
2
Michal

La solution permettant d'ajouter une ombre manuellement fonctionnerait tant qu'il n'y aurait pas de menus dans la barre d'actions. Si tel est le cas, la vue fantôme s’arrêterait avant les icônes de la barre d’action.

je pense qu’il est plus facile d’avoir une disposition linéaire verticale avec la barre d’application en haut et une vue de l’ombre en dessous, comme élément de disposition linéaire suivant ou, dans mon cas, il

<LinearLayout Vertical> 
  <v7 toolbar/>
  <RelativeLayout>
     <View for shadow with alignParent_top= true/>
      ....
  </RelativeLayout>
</LinearLayout>

J'espère vraiment que l'appCompat du futur proche réglera ce problème.

1
onusopus

Une autre option est la bibliothèque suivante qui fournit des ombres 9patch comme l'application iosched, Android-materialshadowninepatch

0
Osiloke