web-dev-qa-db-fra.com

Comment imiter le style de bouton en relief Matériau-design, même pour les pré-Lollipop (moins les effets spéciaux)?

Google a montré de bonnes manières d'afficher les boutons sur Lollipop here .

Je parle à la fois des boutons en relief et des boutons plats.

Comment puis-je les imiter sur les versions antérieures à Lollipop, à l'exception des effets spéciaux (ondulation, etc.)?

Je parle de this et this .

Bien sûr, sur Lollipop et au-dessus, j'aimerais utiliser les effets spéciaux.

Je sais qu'il existe déjà de nombreux (et même plusieurs) messages à ce sujet, mais je ne vois personne qui essaie de l'imiter complètement.

42
android developer

Réponse mise à jour: Il est recommandé de vous fier à la bibliothèque appcompat de Google pour importer les styles de conception de matériel dans votre application. Il semble que le bouton surélevé ne soit plus importé (à la place, à l’aide de boutons plats), mais qu’il reste toujours suffisamment d’arrière-plan, un bouton qui correspond au style de conception du matériau. Je vous recommande de suivre cette approche.

Si vous souhaitez toujours effectuer un backport sur l'effet de bouton en relief, vous devrez vous appuyer sur une bibliothèque de conception de matériel tierce partie. Vous pouvez également consulter l'ancienne solution ci-dessous à l'aide de CardView et implémenter la vôtre.

Pour configurer la bibliothèque appcompat avec le portage officiel de Google Material Design:

compile "com.Android.support:appcompat-v7:+"

Ensuite, vous devez définir le thème de votre application dans votre styles.xml fichier.

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Et dans votre AndroidManifest.xml assurez-vous que le thème ci-dessus est correctement défini:

<application
    Android:allowBackup="false"
    Android:icon="@mipmap/ic_launcher"
    Android:label="@string/app_name"
    Android:supportsRtl="false"
    Android:theme="@style/AppTheme">

Après la configuration ci-dessus, assurez-vous que tous vos Activity s'étendent de AppCompatActivity, et à partir de là, tous vos Buttons seront gonflés avec un style de conception de matériau.

Si vous utilisez une implémentation personnalisée Button dans votre projet, assurez-vous qu'au lieu d'étendre Button, étendez AppCompatButton. Cela vaut pour la plupart de vos personnalités Views: AppCompatTextView, AppCompatEditText, etc ...

Comment ça marche? Toutes vos présentations Android xml sont gonflées à l'aide de quelque chose appelé LayoutInflater . Le LayoutInflater est fourni par le Activity, et a la possibilité d’avoir un LayoutInflaterFactory fourni afin que vous puissiez remplacer les implémentations par défaut de standard Android, comme Button et TextView. Lorsque vous utilisez un AppCompatActivity, il vous fournit un LayoutInflater non standard qui gonfle des instances spéciales des widgets qui prennent en charge Material Design!

----------------------------------------- -------- Ancienne réponse: --- ----------------------------------------------

Donc Android nous a fourni le CardView pour reproduire un tel comportement. Il fournit une vue avec des coins arrondis, qui applique une ombre portée. Vous voudrez probablement aussi regarder à la méthode # setCardElevation () .

Vous pouvez ajouter la bibliothèque CardView à votre projet Gradle:

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

CardView utilisera l’implémentation Lollipop pour effectuer cette opération si elle est disponible (les ombres Lollipops étant meilleures), sinon elle le répliquera du mieux possible.

Voici un échantillon:

<Android.support.v7.widget.CardView
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:card_view="http://schemas.Android.com/apk/res-auto"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        card_view:cardBackgroundColor="#ffd9d9d9"
        card_view:cardCornerRadius="2dp"
        Android:layout_margin="6dp"
        card_view:cardElevation="6dp">

    <TextView Android:id="@+id/text"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:paddingTop="8.5dp"
            Android:paddingBottom="8.5dp"
            Android:paddingLeft="12dp"
            Android:paddingRight="12dp"
            Android:textColor="#de000000"
            Android:fontFamily="sans-serif-medium"
            Android:text="NORMAL" />

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

Le code ci-dessus s'exécutant sur 5.0: CardView Button on 5.0

Le code ci-dessus sous 4.4.4: CardView Button on 4.4.4

Il semble y avoir une différence dans les polices, car dans le sans-serif-medium, le poids de la police est différent ou n'est pas pris en charge par la version 4.4.4, mais cela peut être facilement corrigé en incluant la dernière version de Roboto et en remplaçant le paramètre. polices sur les TextViews.

La documentation sur les matériaux que vous postez pointe vers un "bouton surélevé". CardView est ce que nous faisons de "Elevated" quoi que ce soit.

21
spierce7

Ajoutez la bibliothèque compat à votre application. (La version la plus récente peut être trouvée ici .) Faites ceci en ajoutant une dépendance dans votre fichier build.gradle:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.Android.support:appcompat-v7:21.0.3'
}

Déclarez votre apptheme dans un fichier styles.xml situé dans le répertoire de valeurs:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/theme_primary</item>
        <item name="colorAccent">@color/theme_accent_1</item>
        <item name="actionMenuTextColor">@color/theme_text</item>
    </style>
</resources>

Définissez le style déclaré comme celui à utiliser pour votre application dans le fichier manifest.xml:

<application
    Android:icon="@drawable/ic_launcher"
    Android:theme="@style/AppTheme"/>

Dans vos mises en page, déclarez un bouton en relief comme suit

<Button
    Android:id="@+id/addButton"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:text="@string/title_add" />

Déclarez un style de bouton plat comme suit:

<Button
    Android:id="@+id/okbutton"
    style="?android:attr/borderlessButtonStyle"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@Android:string/ok" />

Résultat sur un appareil 4.4 (un téléphone) et 5.0 (une tablette):

Tablet with 5.0

Phone 4.4

Les détails peuvent être trouvés dans la documentation officielle: http://developer.Android.com/training/material/theme.html

9
Peter

J'obtiens le même effet en utilisant,

  Android:background="@Android:drawable/dialog_holo_light_frame"

Ma sortie testée:

enter image description here

7
Ranjith Kumar

Celui-ci est hacky selon Yigit (google dev sur cardview) mais fait un travail de descente.

Vous pouvez utiliser des nombres négatifs pour vous débarrasser du remplissage et de la marge à l'intérieur de CardView.

Testé sur les émulateurs api 15 nexus one et nexus 4. Cette solution fonctionnera sur pré Lollipop.

<Android.support.v7.widget.CardView
    Android:id="@+id/elevated_button_card"
    card_view:cardElevation="2dp"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    card_view:cardMaxElevation="8dp"
    card_view:contentPadding="-2dp"
    Android:layout_marginBottom="-2dp"
    card_view:cardCornerRadius="0dp">
    <Button
        Android:id="@+id/elevated_button"
        style="?android:attr/borderlessButtonStyle"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:text="Add New Exercise"/
</Android.support.v7.widget.CardView>

Code:

        final CardView cardView = (CardView) rootView.findViewById(R.id.elevated_button_card);
        final Button button = (Button) rootView.findViewById(R.id.elevated_button);
        button.setOnTouchListener(new View.OnTouchListener() {
            ObjectAnimator o1 = ObjectAnimator.ofFloat(cardView, "cardElevation", 2, 8)
                    .setDuration
                            (80);
            ObjectAnimator o2 = ObjectAnimator.ofFloat(cardView, "cardElevation", 8, 2)
                    .setDuration
                            (80);

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        o1.start();
                        break;
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        o2.start();
                        break;
                }
                return false;
            }
        });
4
Asi Mugrabi

Je travaille sur une bibliothèque de compatibilité matérielle. J'ai écrit ma propre classe Button avec des styles ressemblant à des matériaux, des ombres animées et un effet d'entraînement tactile. Bien que ce ne soit pas encore parfait, vous pouvez l'essayer ici .

2
Zielony

En plus de @ spierce7 answer, j'ai légèrement amélioré cette disposition. Alors maintenant, il a une disposition relative dans ce qui définit notre coutume TextView exactement au centre de CardView. Alors voilà.

<Android.support.v7.widget.CardView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        card_view:cardBackgroundColor="@color/colorPrimary"
        card_view:cardCornerRadius="1dp"
        card_view:cardElevation="3dp"
        Android:longClickable="false"
        Android:id="@+id/button">

        <RelativeLayout
            Android:layout_width="match_parent"
            Android:layout_height="48dp"> //just my custom height

        <com.example.admin.lanet_contactwork.MyTextView //for below 5.0
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            PipBoy:fontName="Roboto-Medium.ttf" //custom font
            Android:text="@string/enter"
            Android:textColor="@Android:color/white"
            Android:textSize="14sp"
            Android:layout_centerInParent="true"
            />
        </RelativeLayout>

    </Android.support.v7.widget.CardView>
0
RexSplode

Voir ma réponse pour une solution en conservant la bordure et l'effet en relief sur les pré-Lollipop tout en conservant l'effet d'entraînement sur Lollipop sans inconvénient ici

0
Rémy DAVID