programacion - manual de android en pdf
¿Cómo mostrar sombra alrededor del linearlayout en Android? (12)
¿Cómo puedo mostrar la sombra de mi diseño lineal? Quiero fondo redondeado de color blanco con sombra alrededor de la distribución lineal. He hecho esto hasta ahora. Por favor, ayúdame. Gracias por adelantado.
<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>
Y rounded_rect_shape.xml en el directorio 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>
- guarde este 9.png. (cambie el nombre a
9.png
)
2. Guardalo en tu drawable
.
3. configurarlo en su diseño.
4. ajuste relleno.
Por ejemplo :
<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>
Bueno, esto es fácil de lograr.
Simplemente construya un GradientDrawable
que provenga de color negro y vaya a un color transparente, que use la relación padre para colocar su forma cerca de la Vista que desea que tenga una sombra, entonces solo debe dar cualquier valor a alto o ancho.
Aquí hay un ejemplo, este archivo debe ser creado dentro de res/drawable
, lo shadow.xml
como 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>
Coloque el siguiente código arriba de LinearLayout
, por ejemplo, configure android:layout_width
y android:layout_height
para fill_parent
y 2.3dp
, tendrá un bonito efecto de sombra en su 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>
Nota 1: si aumenta android:layout_height
más sombras.
Nota 2: Utilice el android:layout_above="@+id/id_from_your_LinearLayout"
si coloca este código dentro de RelativeLayout, de lo contrario ignórelo.
Espero que ayude a alguien.
Cree un nuevo XML con el nombre llamado "shadow.xml" en DIBUJO con el siguiente código (puede modificarlo o buscar otro mejor):
<?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>
Después de crear el XML en LinearLayout u otro Widget que desee crear sombreado, use la propiedad ANTECEDENTES para ver el efecto. Sería algo así como:
<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">
En realidad, estoy de acuerdo con @pestbreiner pero coloco el cuadro de diálogo dentro de la primera capa y escondo el fondo negro debajo de la capa blanca.
<?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>
No existe tal atributo en Android, para mostrar una sombra. Pero las formas posibles de hacerlo son:
Agregue un LinearLayout sencillo con color gris, sobre el cual agregue su diseño real, con margen en la parte inferior y derecha igual a 1 o 2 dp
Tener una imagen de 9 parches con una sombra y establecerla como fondo de su diseño lineal
Para lollipop y arriba puedes usar la elevation .
Para versiones anteriores:
Aquí hay un hack perezoso de: http://odedhb.blogspot.com/2013/05/android-layout-shadow-without-9-patch.html
(toast_frame no funciona en KitKat, shadow fue eliminado de los brindis)
Solo usa:
android:background="@android:drawable/toast_frame"
o:
android:background="@android:drawable/dialog_frame"
como fondo
ejemplos:
<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"
/>
y con diferente color bg:
<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>
Prueba esto .. 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>
Aplicar a su diseño de esta manera
android:background="@drawable/layout_shadow"
Puede usar la siguiente clase para la etiqueta 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);
}
}
usa Tag en xml así:
<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>
ACTUALIZAR
ponga el siguiente código en attrs.xml en recursos >> valores
<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>
Sé que esto es demasiado tarde. pero tenía el mismo requisito. lo solucioné así
<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>
necesitas agregar dependencia:
compile ''com.android.support:cardview-v7:25.0.1''
También hay otra solución al problema implementando una lista de capas que actuará como fondo para LinearLayout.
Agrega el archivo background_with_shadow.xml a res/drawable
. Que contiene:
<?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>
A continuación, agregue la lista de capas como fondo en LinearLayout.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/background_with_shadow"/>
Una posible solución es usar nueve imágenes de parche como esta http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
O
He hecho esto de la siguiente manera. Este es mi diseño principal en el que round_corner.xml y drop_shadow.xml se utilizan como recurso de fondo. round_corner_two es lo mismo que round_corner.xml, solo el atributo de color es diferente. copia el round_corner.xml, drop_shadow.xml y round_conere_two.xml en una carpeta dibujable.
<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>
establece este xml drwable como fondo;
<?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>