web-dev-qa-db-fra.com

Ajouter une hauteur / ombre sur la barre d'outils pour les appareils pré-Lollipop

J'ai mis à jour mon Android application) avec le nouveau design de matériau, mais je souhaitais également ajouter une ombre ou une élévation à la barre d'outils. -patches, mais je me demande si cela peut être fait via les bibliothèques de support (tout comme le CardView peut avoir une élévation)

Selon la réponse de this à une autre question, cela est possible en enveloppant le Toolbar dans un AppBarLayout, mais cela ne fonctionne pas pour moi.

Ma mise en page:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.AppBarLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
  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="wrap_content"
            Android:minHeight="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"
            Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</Android.support.design.widget.AppBarLayout>

J'ai également essayé de définir l'altitude via XML et via le code, mais cela ne fonctionne pas non plus.

Toute aide serait appréciée! Merci d'avance.

Mise à jour:

Puisque j'inclus ma mise en forme dans la barre d'outils dans mes autres mises en page, voici l'une de mes mises en page principales:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
    <include
        layout="@layout/Toolbar" />
    <fragment
        class="OverAllField.XamarinAndroid.Fragments.Planning.PlanningFragment"
        Android:id="@+id/PlanningFragment"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="1" />
</LinearLayout>
36
avb

Pour Android 5.0 et supérieur: AppBarLayout fournit/donne automatiquement des ombres dans la présentation. Vous pouvez également augmenter l’altitude de AppBarLayout de app:elevation="4dp".

Pour les pré-sucettes: Vous pouvez utiliser le lien suivant: https://github.com/vipulasri/Toolbar-Elevation-Pre-Lollipop

Remarque: La barre d’outils prend également en charge l’élévation, en utilisant Android:elevation="4dp"


Nouvelle mise à jour: Dans Appcompat v24.0.0, vous ne pouvez pas définir l'élévation sur AppBarLayout à l'aide de setElevation() et app:elevation car ils sont obsolètes.

Vous devez utiliser la propriété stateListAnimator pour définir l'altitude maintenant.

Remarque: définissez la durée sur 1 ms dans StateListAnimator afin de éviter les retards dans le dessin en élévation.

Le changement d'élévation AppBarLayout est retardé sur appCompat v24.0.

appbar_always_elevated.xml dans animator-v21 dossier sous = res répertoire.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item>
    <objectAnimator Android:propertyName="elevation"
                    Android:valueTo="8dp" 
                    Android:valueType="floatType"
                    Android:duration="1"/>
</item>
</selector>

Dans AppbarLayout:

<Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="300dp"
        Android:fitsSystemWindows="true"
        Android:stateListAnimator="@animator/appbar_always_elevated"
        Android:theme="@style/AppTheme.AppBarOverlay">

</Android.support.design.widget.AppBarLayout>
63
Vipul Asri

Essayez d'utiliser AppBarLayout dans la présentation de l'activité. Essayer:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

        <include
            layout="@layout/Toolbar" />
    </Android.support.design.widget.AppBarLayout>

    <fragment
        class="OverAllField.XamarinAndroid.Fragments.Planning.PlanningFragment"
        Android:id="@+id/PlanningFragment"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        Android:layout_weight="1" />
</LinearLayout>

Toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.Toolbar
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/Toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:minHeight="?attr/actionBarSize"
    Android:background="?attr/colorPrimary"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
7
Binoy Babu

utiliser le fichier de construction:


compile 'com.Android.support:cardview-v7:23.1.1'

voir ce lien

appeler en xml ajouter:

app:cardElevation="8dp"
app:cardCornerRadius="8dp"
app:contentPadding="5dp"
2
Ankush.Rana

J'ai un CollapsingToolbarLayout avec Toolbar et une barre semblable à une barre d'outils View qui monte et descend, mais se situe au-dessus de NestedScrollView, comme dans https : //github.com/k0shk0sh/CoordinatorLayoutExample . J'ai essayé beaucoup de variantes. Parfois, une ombre défilait au-dessus d'un écran avec NestedScrollView, parfois la barre d'outils dessinait une ombre pleine sans transparence, parfois l'ombre était aliasée. Quoi qu'il en soit, c'est ma solution.

Dis, tu as une mise en page:

<Android.support.design.widget.CoordinatorLayout>
    <Android.support.design.widget.AppBarLayout>
         <Android.support.design.widget.CollapsingToolbarLayout>
             <Android.support.v7.widget.Toolbar>
                 <!-- Toolbar views if needed -->
             </Android.support.v7.widget.Toolbar>
        </Android.support.design.widget.CollapsingToolbarLayout>
    </Android.support.design.widget.AppBarLayout>

    <!-- Footer Toolbar views if needed -->

    <Android.support.v4.widget.NestedScrollView
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout>
            <!-- Views -->
        </LinearLayout>

    </Android.support.v4.widget.NestedScrollView>

    <!-- Add this view. It draws a shadow and aligns top of NestedScrollView -->
    <!-- Set visibility to gone or visible -->
    <View
        Android:id="@+id/scroll_shadow"
        Android:layout_width="match_parent"
        Android:layout_height="4dp"
        Android:background="@drawable/shadow"
        Android:visibility="gone"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</Android.support.design.widget.CoordinatorLayout>

Ajoutez une ombre ( drawable/shadow.xml ):

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <gradient
        Android:angle="90"
        Android:endColor="#ffcccccc"
        Android:startColor="#00cccccc" />
</shape>

Ajoutez cette méthode. ScrollShadow est une vue nommée "scroll_shadow":

private void setShadowVisibility(int visibility) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
        scrollShadow.setVisibility(visibility);
    }
}

Manipulez-le comme vous le souhaitez. Il montrera un dégradé sur les appareils pré-Lollipop et montrera une ombre normale pour Android 5.0+.

2
CoolMind

Je pense que la meilleure solution est de placer une vue ombrée en dégradé sous la barre d’outils et de manipuler avec une visibilité qui dépend du périphérique sdk.

toolbar.xml

 <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:app="http://schemas.Android.com/apk/res-auto"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical">

        <Android.support.v7.widget.Toolbar xmlns:Android="http://schemas.Android.com/apk/res/Android"
            xmlns:app="http://schemas.Android.com/apk/res-auto"
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="@Android:color/white"
            Android:fitsSystemWindows="true"
            app:popupTheme="@style/AppTheme.PopupOverlay">

            <TextView
                Android:id="@+id/centerTitleToolbarTextView"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:gravity="center"
                Android:maxLines="1"
                Android:textColor="@color/color_toolbar"
                Android:textSize="@dimen/titleToolbar" />

        </Android.support.v7.widget.Toolbar>

        <View
            Android:id="@+id/shadow_view"
            Android:layout_width="match_parent"
            Android:visibility="gone"
            Android:layout_height="4dp"
            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="#c1c1c1"
        Android:centerColor="#e6e6e6"
        Android:endColor="#f1f1f1"
        Android:angle="270" />
</shape>

MainActivity.class

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Lollipop) {
        findViewById(R.id.shadow_view).setVisibility(View.VISIBLE);
      }
1
Levon Petrosyan

J'ai également perdu un jour sur cette question, mais j'ai finalement trouvé un moyen de le faire fonctionner.

/**
 * Controller for the toolbar which will take care of the drop down shadow also on pre-Lollipop devices.
 * <br/>
 * The controller also handles the status bar based on the state of the toolbar.
 * <p/>
 * Created by <b>Negru Ionut Valentin</b> on <b>20/1/2016</b>.
 */
public class ToolbarController {

    private boolean handleStatusBar = false;
    private boolean showTitle = true;

    /**
     * Call this method in onCreate() method of your Activity or in onCreateView() in Fragment
     *
     * @param view
     *         The view into which to look for the toolbar
     * @param activity
     *         The activity for which setup the toolbar
     *
     * @return The toolbar found and customized or {@code null}
     */
    public Toolbar initToolbar(View view, Activity activity) {
        Toolbar mToolbar = (Toolbar) view.findViewById(R.id.toolbar);

        // Valid and visible toolbar - otherwise ignore
        if (null != mToolbar && mToolbar.getVisibility() == View.VISIBLE) {

            int paddingLeft = mToolbar.getPaddingLeft();
            int paddingRight = mToolbar.getPaddingRight();
            int paddingBottom = mToolbar.getPaddingBottom();
            // Set the top padding of the toolbar to match the status bar height
            int paddingTop = new CynnyContextWrapper(activity).getStatusBarHeight();

            mToolbar.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);

            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Lollipop) {
                ViewParent parent = mToolbar.getParent();
                if (parent instanceof RelativeLayout) {
                    // Manually create the drop shadow
                    RelativeLayout.LayoutParams params =
                            new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                                            Metrics.convertDpToPixel(4, activity));

                    View dropShadow = new View(activity);
                    dropShadow.setBackgroundResource(R.drawable.toolbar_shadow);

                    params.addRule(RelativeLayout.BELOW, R.id.toolbar);

                    ((RelativeLayout) parent).addView(dropShadow, params);
                }
            }

            if (activity instanceof AppCompatActivity) {
                // Check if the Activity actually support ActionBar with Toolbar and set our custom Toolbar for it
                ((AppCompatActivity) activity).setSupportActionBar(mToolbar);

                // Get the actionbar from the activity
                ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar();
                if (null != actionBar) {
                    // If the actionbar is valid, customize it
                    actionBar.setDisplayHomeAsUpEnabled(true);
                    actionBar.setHomeButtonEnabled(true);

                    actionBar.setDisplayShowTitleEnabled(this.showTitle);

                    mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_selector);
                }
            }

            if (this.handleStatusBar) {
                // For showing the status bar
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
            }
        } else if (handleStatusBar) {
            // Force hide the status bar
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        }

        return mToolbar;
    }

    /**
     * Set the flag indicating if the controller should handle or not the status bar.
     *
     * @param handleStatusBar
     *         Flag which indicates if the initialization of the toolbar should also update
     *         the status bar state (if two calls are made for the init, the last one will
     *         be taken into consideration).
     *
     * @return The current toolbar controller.
     */
    public ToolbarController setHandleStatusBar(boolean handleStatusBar) {
        this.handleStatusBar = handleStatusBar;

        return this;
    }

    /**
     * Set the flag indicating if the toolbar should show or hide the title.
     *
     * @param showTitle
     *         Flag indicating if the toolbar should also show the title (the title can be changed after the toolbar
     *         initialization)
     *
     * @return The current toolbar controller.
     */
    public ToolbarController setShowTitle(boolean showTitle) {
        this.showTitle = showTitle;

        return this;
    }
}

Dans l'activité, vous devriez utiliser ceci dans la méthode onCreate () comme ceci:

// Create and customize the Toolbar controller
new ToolbarController().setHandleStatusBar(true).setShowTitle(true)
                                 .initToolbar(((ViewGroup) findViewById(Android.R.id.content)).getChildAt(0),
                                              this);

Dans le fragment, vous devriez utiliser ceci dans la méthode onCreateView () comme ceci:

new ToolbarController().setHandleStatusBar(false).setShowTitle(false).initToolbar(resultView, getActivity());

N'oubliez pas d'ajouter votre barre d'outils dans les mises en page et de définir son identifiant avec Android:id="@id/toolbar". Si vous souhaitez utiliser un autre identifiant, vous pouvez personnaliser le contrôleur et ajouter une autre méthode de définition utilisant l'identifiant fourni.

J'ai deux configurations de barre d'outils créées:

v21

    <!-- This is the new widget added in Lollipop - use with care -->
    <Android.support.v7.widget.Toolbar
            Android:id="@id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:minHeight="?attr/actionBarSize"
            Android:theme="@style/TitleToolbarTheme"
            Android:background="?android:attr/colorPrimary"
            Android:elevation="@dimen/toolbar_elevation"
            />
</merge>

autre

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:Android="http://schemas.Android.com/apk/res/Android"
        >

    <!-- This is the new widget added in Lollipop - use with care -->
    <Android.support.v7.widget.Toolbar
            Android:id="@id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:minHeight="?attr/actionBarSize"
            Android:theme="@style/TitleToolbarTheme"
            Android:background="?attr/colorPrimary"
            />

</merge>

Je les utilise dans les mises en page de mai en utilisant:

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

J'espère que cela aidera à résoudre votre problème. Notez également que cela peut être optimisé davantage, mais cela fonctionne pour moi et je ne veux plus perdre de temps sur ce sujet.

0
Ionut Negru