2010-08-25 33 views
30

J'ai fait une recherche approfondie d'exemples de code sur ce sujet, mais je ne trouve rien.Android Drop Shadow sur View

En particulier, je cherche à ajouter une ombre à un dessinable png que j'utilise dans un ImageView. Ce png drawable est un rectangle arrondi avec des coins transparents. Est-ce que quelqu'un peut donner un exemple de code pour ajouter une ombre portée décente à une vue en code ou en XML?

+0

vous pouvez facilement générer des ombres ninepatch en utilisant cet outil http://inloop.github.io/shadow4android/ – Yuraj

Répondre

29

Vous pouvez utiliser une combinaison de Bitmap.extractAlpha et d'un BlurMaskFilter pour créer manuellement une ombre portée pour toute image que vous devez afficher, mais cela ne fonctionnerait que si votre image n'est chargée/affichée qu'une fois de temps en temps. le processus est cher.

pseudo-code (pourrait même compiler!):

BlurMaskFilter blurFilter = new BlurMaskFilter(5, BlurMaskFilter.Blur.OUTER); 
Paint shadowPaint = new Paint(); 
shadowPaint.setMaskFilter(blurFilter); 

int[] offsetXY = new int[2]; 
Bitmap shadowImage = originalBitmap.extractAlpha(shadowPaint, offsetXY); 

/* Might need to convert shadowImage from 8-bit to ARGB here, can't remember. */ 

Canvas c = new Canvas(shadowImage); 
c.drawBitmap(originalBitmap, offsetXY[0], offsetXY[1], null); 

ensuite mis shadowImage dans votre ImageView. Si cette image ne change jamais mais s'affiche beaucoup, vous pouvez la créer et la mettre en cache dans onCreate pour contourner le traitement coûteux de l'image.

Même si cela ne fonctionne pas tel quel, cela devrait suffire à vous faire avancer dans la bonne direction.

+3

Il a travaillé en quelque sorte ... Une fois que je a changé les offsetXY [[0] et [1] dans drawBitmap pour être négatif de ces valeurs alignées correctement. Toutefois, le bitmap d'origine dessine comme une image noire solide. http://cl.ly/77e6b7839c1ffc94c1e0 Comment réparer? – coneybeare

+0

Je ne suis pas sûr de voir le code. Essayez de vérifier les bitdepths des bitmaps source et destination. Le problème peut être que vous dessinez une image 32 bits (l'original) sur une image 8 bits (l'image shadowImage extraite). Si c'est le cas, faites quelque chose comme Bitmap shadowImage32 = shadowImage.copy (ARGB_8888, true) là où j'ai le commentaire de conversion, et dessinez sur ce type au lieu de l'image shadow 8 bits. – Josh

+0

Bonjour @Josh J'utilise votre code. Son fonctionnement mais comment pouvons-nous changer la couleur de l'ombre? –

25

Pour une utilisation ombre descendre en dessous du code

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <gradient 
    android:startColor="#ffffff" 
    android:centerColor="#d3d7cf" 
    android:endColor="#2e3436" 
    android:angle="90" /> 
</shape> 

utilisation ci-dessus drawable pour un fond d'une vue

<View 
    android:id="@+id/divider" 
    android:background="@drawable/black_white_gradient" 
    android:layout_width="match_parent" 
    android:layout_height="10sp" 
    android:layout_below="@+id/buildingsList"/> 
+8

Ce n'est pas expliqué aussi bien qu'il pourrait l'être, mais ce n'est pas une mauvaise approche. Le point clé est que la vue avec le dégradé en arrière-plan est une vue séparée qui doit être positionnée immédiatement en dessous de la vue sur laquelle vous voulez que l'ombre apparaisse. Cela fonctionne mieux lorsque la vue à ombrer prend toute la largeur de l'écran, sinon les coins sembleront faux. –

+0

Ceci est une approche pour les situations déclaratives, mais dans mon cas, je crée un nombre dynamique de boutons dans le code en fonction de la lecture des données, donc ce n'est pas très utile pour mon cas. – jrichview

8

Cela m'a aidé à obtenir l'ombre travailler si je voulais partager le code de travail:

private Bitmap createShadowBitmap(Bitmap originalBitmap) { 
    BlurMaskFilter blurFilter = new BlurMaskFilter(5, BlurMaskFilter.Blur.OUTER); 
    Paint shadowPaint = new Paint(); 
    shadowPaint.setMaskFilter(blurFilter); 

    int[] offsetXY = new int[2]; 
    Bitmap shadowImage = originalBitmap.extractAlpha(shadowPaint, offsetXY); 

    /* Need to convert shadowImage from 8-bit to ARGB here. */ 
    Bitmap shadowImage32 = shadowImage.copy(Bitmap.Config.ARGB_8888, true); 
    Canvas c = new Canvas(shadowImage32); 
    c.drawBitmap(originalBitmap, -offsetXY[0], -offsetXY[1], null); 

    return shadowImage32; 
} 
3

Pour API 21 (5.0) + ajouter android:elevation="4dp" ou android:translationZ="4dp" pour voir la description. Documentation

Elevation Attribute

1

Utilisez toujours l'ombre transparente de telle sorte qu'ils puissent en tenir à une couleur.

shadow.xml

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <gradient 
    android:startColor="#002e3436" 
    android:endColor="#992e3436" 
    android:angle="90" /> 
</shape> 

Et Voir

<View 
    android:id="@+id/divider" 
    android:background="@drawable/shadow" 
    android:layout_width="match_parent" 
    android:layout_height="5dp"/>