web-dev-qa-db-fra.com

Comment afficher l'ombre autour de la linéarité dans Android?

Comment puis-je montrer l'ombre pour ma mise en page linéaire. Je veux un fond arrondi de couleur blanche avec des ombres autour de la représentation linéaire. Je l'ai fait jusqu'à présent. Aidez-moi, s'il vous plaît. Merci d'avance.

<LinearLayout
 Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_margin="10dp"
Android:background="@xml/rounded_rect_shape"
Android:orientation="vertical"
Android:padding="10dp">
<-- My buttons, textviews, Imageviews go here -->
</LinearLayout>

Et rounded_rect_shape.xml sous le répertoire xml

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

   <solid Android:color="#ffffff" />

   <corners
      Android:bottomLeftRadius="3dp"
      Android:bottomRightRadius="3dp"
      Android:topLeftRadius="3dp"
      Android:topRightRadius="3dp" />
</shape>
74
Santhosh

Il n'y a pas un tel attribut dans Android, pour montrer une ombre. Mais les moyens possibles de le faire sont:

  1. Ajoutez un LinearLayout uni avec une couleur grise, sur lequel ajoutez votre mise en page actuelle, avec une marge en bas et à droite égale à 1 ou 2 dp

  2. Avoir une image de 9 patchs avec une ombre et la définir comme arrière-plan de votre mise en page linéaire

25
Archie.bpgc

Il existe également une autre solution au problème en mettant en œuvre une liste de couches qui servira de fond pour LinearLayoout.

Ajoutez le fichier background_with_shadow.xml à res/drawable. Contenant:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item >
        <shape 
            Android:shape="rectangle">
        <solid Android:color="@Android:color/darker_gray" />
        <corners Android:radius="5dp"/>
        </shape>
    </item>
    <item Android:right="1dp" Android:left="1dp" Android:bottom="2dp">
        <shape 
            Android:shape="rectangle">
        <solid Android:color="@Android:color/white"/>
        <corners Android:radius="5dp"/>
        </shape>
    </item>
</layer-list>

Ajoutez ensuite la liste de calques en tant qu'arrière-plan de votre LinearLayout.

<LinearLayout
  Android:layout_width="wrap_content"
  Android:layout_height="wrap_content"
  Android:background="@drawable/background_with_shadow"/>
142
muthee

Eh bien, c'est facile à réaliser.

Il suffit de construire un GradientDrawable qui provient du noir et passe à une couleur transparente, puis utilisez une relation parentale pour placer votre forme près de la vue pour laquelle vous souhaitez créer une ombre. ou largeur.

Voici un exemple, ce fichier doit être créé dans res/drawable, Je l’appelle comme 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="#9444"
        Android:endColor="#0000"
        Android:type="linear"
        Android:angle="90"> <!-- Change this value to have the correct shadow angle, must be multiple from 45 -->
    </gradient>

</shape>

Placez le code ci-dessus à partir de LinearLayout, par exemple, définissez les paramètres Android:layout_width Et Android:layout_height Sur fill_parent Et 2.3dp, avoir un bel effet d’ombre sur votre LinearLayout.

<View
    Android:id="@+id/shadow"
    Android:layout_width="fill_parent"
    Android:layout_height="2.3dp"  
    Android:layout_above="@+id/id_from_your_LinearLayout" 
    Android:background="@drawable/shadow">
</View>

Note 1: Si vous augmentez Android:layout_height, Plus d'ombre sera affichée.

Note 2: Utilisez l'attribut Android:layout_above="@+id/id_from_your_LinearLayout" Si vous placez ce code dans un RelativeLayout, sinon ignorez-le.

J'espère que ça aidera quelqu'un.

28
Murillo Ferreira

Pour Lollipop et au-dessus, vous pouvez utiliser altitude .

Pour les anciennes versions:

Voici un hack paresseux de: http://odedhb.blogspot.com/2013/05/Android-layout-shadow-without-9-patch.html

(toast_frame ne fonctionne pas sur KitKat, l'ombre a été supprimée des toasts)

juste utiliser:

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

ou:

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

comme arrière-plan

exemples:

<TextView
        Android:layout_width="fill_parent"
        Android:text="I am a simple textview with a shadow"
        Android:layout_height="wrap_content"
        Android:textSize="18sp"
        Android:padding="16dp"
        Android:textColor="#fff"
        Android:background="@Android:drawable/toast_frame"
        />

et avec une couleur différente:

<LinearLayout
        Android:layout_height="64dp"
        Android:layout_width="fill_parent"
        Android:gravity="center"
        Android:background="@Android:drawable/toast_frame"
        Android:padding="4dp"
        >
    <Button
            Android:layout_width="fill_parent"
            Android:layout_height="fill_parent"
            Android:text="Button shadow"
            Android:background="#33b5e5"
            Android:textSize="24sp"
            Android:textStyle="bold"
            Android:textColor="#fff"
            Android:layout_gravity="center|bottom"
            />

</LinearLayout>
17
Oded Breiner

Essayez ceci .. layout_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item>
        <shape Android:shape="rectangle">
            <solid Android:color="#CABBBBBB"/>
            <corners Android:radius="2dp" />
        </shape>
    </item>

    <item
        Android:left="0dp"
        Android:right="0dp"
        Android:top="0dp"
        Android:bottom="2dp">
        <shape Android:shape="rectangle">
            <solid Android:color="@Android:color/white"/>
            <corners Android:radius="2dp" />
        </shape>
    </item>
</layer-list>

Appliquer à votre mise en page comme ceci

 Android:background="@drawable/layout_shadow"
11
King of Masses

En fait, je suis d’accord avec @odedbreiner mais j’ai placé le dialog_frame dans le premier calque et caché le fond noir sous le calque blanc.

    <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item
        Android:drawable="@Android:drawable/dialog_frame"
        Android:right="2dp" Android:left="2dp" Android:bottom="2dp" Android:top="5dp" >
        <shape Android:shape="rectangle">
            <corners Android:radius="5dp"/>
        </shape>
    </item>
    <item>
        <shape
            Android:shape="rectangle">
            <solid Android:color="@Android:color/white"/>
            <corners Android:radius="5dp"/>
        </shape>
    </item>
</layer-list>
5
Subkhan Sarif
  1. enregistrer ce 9.png. (changez le nom en 9.png)

enter image description here

2. l'enregistrez dans votre drawable.

3.mettez-le à votre disposition.

Rembourrage 4.set.

Par exemple :

<LinearLayout  
  Android:layout_width="fill_parent"
  Android:layout_height="wrap_content"
  Android:background="@drawable/shadow"
  Android:paddingBottom="6dp"
  Android:paddingLeft="5dp"
  Android:paddingRight="5dp"
  Android:paddingTop="6dp"
>

.
.
.
</LinearLayout>
3
S.M_Emamian

Je sais que c'est vieux, mais la plupart de ces réponses nécessitent une tonne de code supplémentaire.

Si vous avez un fond de couleur claire, vous pouvez simplement utiliser ceci:

Android:elevation="25dp"
2
Jalen Paul

Créez un nouveau fichier XML avec l'exemple nommé "shadow.xml" dans DRAWABLE avec le code suivant (vous pouvez le modifier ou en trouver un autre meilleur):

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

    <item>
        <shape Android:shape="rectangle">
            <solid Android:color="@color/middle_grey"/>
        </shape>
    </item>

    <item Android:left="2dp"
          Android:right="2dp"
          Android:bottom="2dp">
        <shape Android:shape="rectangle">
            <solid Android:color="@color/white"/>
        </shape>
    </item>

</layer-list>

Après avoir créé le code XML dans LinearLayout ou dans un autre widget que vous souhaitez créer, ombrage, vous utilisez la propriété BACKGROUND pour afficher l’effet. Ce serait quelque chose comme:

<LinearLayout
    Android:orientation="horizontal"
    Android:layout_height="wrap_content"
    Android:layout_width="match_parent"
    Android:paddingRight="@dimen/margin_med"
    Android:background="@drawable/shadow"
    Android:minHeight="?attr/actionBarSize"
    Android:gravity="center_vertical">
2
Javier Amor Penas

Vous pouvez utiliser la classe suivante pour la balise XML:

import Android.annotation.SuppressLint;
import Android.content.Context;
import Android.content.res.TypedArray;
import Android.graphics.Bitmap;
import Android.graphics.BlurMaskFilter;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.PorterDuff;
import Android.graphics.Rect;
import Android.os.Build;
import Android.support.annotation.FloatRange;
import Android.util.AttributeSet;
import Android.view.ViewGroup;
import Android.view.ViewTreeObserver;
import Android.widget.FrameLayout;

import com.webappmate.weeassure.R;

/**
 * Created by GIGAMOLE on 13.04.2016.
 */
public class ShadowLayout extends FrameLayout {

    // Default shadow values
    private final static float DEFAULT_SHADOW_RADIUS = 30.0F;
    private final static float DEFAULT_SHADOW_DISTANCE = 15.0F;
    private final static float DEFAULT_SHADOW_ANGLE = 45.0F;
    private final static int DEFAULT_SHADOW_COLOR = Color.DKGRAY;

    // Shadow bounds values
    private final static int MAX_ALPHA = 255;
    private final static float MAX_ANGLE = 360.0F;
    private final static float MIN_RADIUS = 0.1F;
    private final static float MIN_ANGLE = 0.0F;
    // Shadow Paint
    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG) {
        {
            setDither(true);
            setFilterBitmap(true);
        }
    };
    // Shadow bitmap and canvas
    private Bitmap mBitmap;
    private final Canvas mCanvas = new Canvas();
    // View bounds
    private final Rect mBounds = new Rect();
    // Check whether need to redraw shadow
    private boolean mInvalidateShadow = true;

    // Detect if shadow is visible
    private boolean mIsShadowed;

    // Shadow variables
    private int mShadowColor;
    private int mShadowAlpha;
    private float mShadowRadius;
    private float mShadowDistance;
    private float mShadowAngle;
    private float mShadowDx;
    private float mShadowDy;

    public ShadowLayout(final Context context) {
        this(context, null);
    }

    public ShadowLayout(final Context context, final AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ShadowLayout(final Context context, final AttributeSet attrs, final int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        setWillNotDraw(false);
        setLayerType(LAYER_TYPE_HARDWARE, mPaint);

        // Retrieve attributes from xml
        final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout);

        try {
            setIsShadowed(typedArray.getBoolean(R.styleable.ShadowLayout_sl_shadowed, true));
            setShadowRadius(
                    typedArray.getDimension(
                            R.styleable.ShadowLayout_sl_shadow_radius, DEFAULT_SHADOW_RADIUS
                    )
            );
            setShadowDistance(
                    typedArray.getDimension(
                            R.styleable.ShadowLayout_sl_shadow_distance, DEFAULT_SHADOW_DISTANCE
                    )
            );
            setShadowAngle(
                    typedArray.getInteger(
                            R.styleable.ShadowLayout_sl_shadow_angle, (int) DEFAULT_SHADOW_ANGLE
                    )
            );
            setShadowColor(
                    typedArray.getColor(
                            R.styleable.ShadowLayout_sl_shadow_color, DEFAULT_SHADOW_COLOR
                    )
            );
        } finally {
            typedArray.recycle();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        // Clear shadow bitmap
        if (mBitmap != null) {
            mBitmap.recycle();
            mBitmap = null;
        }
    }

    public boolean isShadowed() {
        return mIsShadowed;
    }

    public void setIsShadowed(final boolean isShadowed) {
        mIsShadowed = isShadowed;
        postInvalidate();
    }

    public float getShadowDistance() {
        return mShadowDistance;
    }

    public void setShadowDistance(final float shadowDistance) {
        mShadowDistance = shadowDistance;
        resetShadow();
    }

    public float getShadowAngle() {
        return mShadowAngle;
    }

    @SuppressLint("SupportAnnotationUsage")
    @FloatRange
    public void setShadowAngle(@FloatRange(from = MIN_ANGLE, to = MAX_ANGLE) final float shadowAngle) {
        mShadowAngle = Math.max(MIN_ANGLE, Math.min(shadowAngle, MAX_ANGLE));
        resetShadow();
    }

    public float getShadowRadius() {
        return mShadowRadius;
    }

    public void setShadowRadius(final float shadowRadius) {
        mShadowRadius = Math.max(MIN_RADIUS, shadowRadius);

        if (isInEditMode()) return;
        // Set blur filter to Paint
        mPaint.setMaskFilter(new BlurMaskFilter(mShadowRadius, BlurMaskFilter.Blur.NORMAL));
        resetShadow();
    }

    public int getShadowColor() {
        return mShadowColor;
    }

    public void setShadowColor(final int shadowColor) {
        mShadowColor = shadowColor;
        mShadowAlpha = Color.alpha(shadowColor);

        resetShadow();
    }

    public float getShadowDx() {
        return mShadowDx;
    }

    public float getShadowDy() {
        return mShadowDy;
    }

    // Reset shadow layer
    private void resetShadow() {
        // Detect shadow axis offset
        mShadowDx = (float) ((mShadowDistance) * Math.cos(mShadowAngle / 180.0F * Math.PI));
        mShadowDy = (float) ((mShadowDistance) * Math.sin(mShadowAngle / 180.0F * Math.PI));

        // Set padding for shadow bitmap
        final int padding = (int) (mShadowDistance + mShadowRadius);
        setPadding(padding, padding, padding, padding);
        requestLayout();
    }

    private int adjustShadowAlpha(final boolean adjust) {
        return Color.argb(
                adjust ? MAX_ALPHA : mShadowAlpha,
                Color.red(mShadowColor),
                Color.green(mShadowColor),
                Color.blue(mShadowColor)
        );
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // Set ShadowLayout bounds
        mBounds.set(
                0, 0, MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)
        );
    }

    @Override
    public void requestLayout() {
        // Redraw shadow
        mInvalidateShadow = true;
        super.requestLayout();
    }

    @Override
    protected void dispatchDraw(final Canvas canvas) {
        // If is not shadowed, skip
        if (mIsShadowed) {
            // If need to redraw shadow
            if (mInvalidateShadow) {
                // If bounds is zero
                if (mBounds.width() != 0 && mBounds.height() != 0) {
                    // Reset bitmap to bounds
                    mBitmap = Bitmap.createBitmap(
                            mBounds.width(), mBounds.height(), Bitmap.Config.ARGB_8888
                    );
                    // Canvas reset
                    mCanvas.setBitmap(mBitmap);

                    // We just redraw
                    mInvalidateShadow = false;
                    // Main feature of this lib. We create the local copy of all content, so now
                    // we can draw bitmap as a bottom layer of natural canvas.
                    // We draw shadow like blur effect on bitmap, cause of setShadowLayer() method of
                    // Paint does`t draw shadow, it draw another copy of bitmap
                    super.dispatchDraw(mCanvas);

                    // Get the alpha bounds of bitmap
                    final Bitmap extractedAlpha = mBitmap.extractAlpha();
                    // Clear past content content to draw shadow
                    mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);

                    // Draw extracted alpha bounds of our local canvas
                    mPaint.setColor(adjustShadowAlpha(false));
                    mCanvas.drawBitmap(extractedAlpha, mShadowDx, mShadowDy, mPaint);

                    // Recycle and clear extracted alpha
                    extractedAlpha.recycle();
                } else {
                    // Create placeholder bitmap when size is zero and wait until new size coming up
                    mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565);
                }
            }

            // Reset alpha to draw child with full alpha
            mPaint.setColor(adjustShadowAlpha(true));
            // Draw shadow bitmap
            if (mCanvas != null && mBitmap != null && !mBitmap.isRecycled())
                canvas.drawBitmap(mBitmap, 0.0F, 0.0F, mPaint);
        }

        // Draw child`s
        super.dispatchDraw(canvas);
    }


}

utilisez Tag en XML comme ceci:

<yourpackagename.ShadowLayout
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignParentBottom="true"
        Android:layout_centerHorizontal="true"
        Android:layout_gravity="center_horizontal"
        app:sl_shadow_color="#9e000000"
        app:sl_shadow_radius="4dp">
<child views>
</yourpackagename.ShadowLayout>

MISE À JOUR

mettez le code ci-dessous dans attrs.xml dans ressource >> valeurs

  <declare-styleable name="ShadowLayout">
    <attr name="sl_shadowed" format="boolean"/>
    <attr name="sl_shadow_distance" format="dimension"/>
    <attr name="sl_shadow_angle" format="integer"/>
    <attr name="sl_shadow_radius" format="dimension"/>
    <attr name="sl_shadow_color" format="color"/>
</declare-styleable>
2
Shashwat Gupta

je sais que c'est beaucoup trop tard. mais j'avais la même exigence. j'ai résolu comme ça

<Android.support.v7.widget.CardView
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:cardUseCompatPadding="true"
app:cardElevation="4dp"
app:cardCornerRadius="3dp" >

<!-- put whatever you want -->

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

vous devez ajouter une dépendance:

compile 'com.Android.support:cardview-v7:25.0.1'
1
JNDanial

Une solution possible consiste à utiliser neuf images de correctif comme celle-ci http://developer.Android.com/guide/topics/graphics/2d-graphics.html#nine-patch

OR

Je l'ai fait de la manière suivante. Ceci est ma mise en page principale dans laquelle round_corner.xml et drop_shadow.xml sont utilisés comme ressource en arrière-plan. round_corner_two est identique à round_corner.xml, seul l'attribut color est différent. copiez les fichiers round_corner.xml, drop_shadow.xml et round_conere_two.xml dans un dossier pouvant être dessiné.

<RelativeLayout
    Android:id="@+id/facebook_id"
    Android:layout_width="250dp"
    Android:layout_height="52dp"
    Android:layout_centerHorizontal="true"
    Android:layout_marginTop="28dp"
    Android:background="@drawable/round_corner" >

    <LinearLayout
        Android:id="@+id/shadow_id"
        Android:layout_width="match_parent"
        Android:layout_height="48dp"
        Android:layout_margin="1dp"
        Android:background="@drawable/drop_shadow" >

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_gravity="center"
            Android:layout_marginBottom="2dp"
            Android:background="@drawable/round_corner_two"
            Android:gravity="center"
            Android:text="@string/fb_butn_text"
            Android:textColor="@color/white" >
        </TextView>
    </LinearLayout>
</RelativeLayout>

round_corner.xml:

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

<!-- view background color -->
<solid
    Android:color="#ffffff" >
</solid>

<!-- view border color and width -->
<stroke
    Android:width="0dp"
    Android:color="#3b5998" >
</stroke>

<!-- If you want to add some padding -->
<padding
    Android:left="1dp"
    Android:top="1dp"
    Android:right="1dp"
    Android:bottom="1dp"    >
</padding>

<!-- Here is the corner radius -->
<corners
    Android:radius="10dp"   >
</corners>

</shape>

drop_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item >
    <shape 
        Android:shape="rectangle">
    <solid Android:color="@Android:color/darker_gray" />
    <corners Android:radius="12dp"/>
    </shape>
</item>
<item Android:right="1dp" Android:left="1dp" Android:bottom="5dp">
    <shape 
        Android:shape="rectangle">
    <solid Android:color="@Android:color/white"/>
    <corners Android:radius="5dp"/>
    </shape>
</item>
</layer-list>
1
raju

définir ce xml dessinable comme fond d'écran; ---

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

<!-- Bottom 2dp Shadow -->
<item>
    <shape Android:shape="rectangle" >
        <solid Android:color="#d8d8d8" />-->Your shadow color<--

        <corners Android:radius="15dp" />
    </shape>
</item>

<!-- White Top color -->
<item Android:bottom="3px" Android:left="3px" Android:right="3px" Android:top="3px">-->here you can customize the shadow size<---
    <shape Android:shape="rectangle" >
        <solid Android:color="#FFFFFF" />

        <corners Android:radius="15dp" />
    </shape>
</item>

</layer-list>
0
Kailash Dabhi