Как показать тень вокруг linearlayout в android?
Как я могу показать тень для моего линейного макета. Я хочу белый цвет округлый фон с тенью вокруг linearlayout. Я сделал это до сих пор. Пожалуйста, помогите мне. Спасибо заранее.
<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>
и rounded_rect_shape.xml под каталогом 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>
13 ответов:
в Android нет такого атрибута, чтобы показать тень. Но возможные способы сделать это:
добавьте простой LinearLayout с серым цветом, над которым добавьте свой фактический макет, с полями внизу и справа, равными 1 или 2 dp
есть 9-патч изображение с тенью и установить его в качестве фона для вашего линейного макета
существует также другое решение проблемы путем реализации списка слоев, который будет выступать в качестве фона для LinearLayoout.
добавить background_with_shadow.xml-файл в
res/drawable
. Содержащий:<?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>
затем добавьте список слоев в качестве фона в свой LinearLayout.
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/background_with_shadow"/>
Ну, это легко достичь .
просто построить
GradientDrawable
это происходит от Черного и переходит к прозрачному цвету, чем использовать родительские отношения, чтобы разместить свою фигуру близко к виду, который вы хотите иметь тень, то вы просто должны дать любые значения высоты или ширины .вот пример, этот файл должен быть создан внутри
res/drawable
, Я называю это как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>
поместите следующий код выше от
LinearLayout
, например, установитеandroid:layout_width
иandroid:layout_height
доfill_parent
и2.3dp
, вы будете иметь хороший эффект тени на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>
Примечание 1: если вы увеличиваете
android:layout_height
будет показано больше тени .примечание 2: использовать
android:layout_above="@+id/id_from_your_LinearLayout"
атрибут если вы размещаете этот код внутри RelativeLayout, в противном случае игнорируйте его.надеюсь, что это поможет кому-то.
для леденца и выше вы можете использовать высота.
для более старых версий:
вот ленивый хак от: http://odedhb.blogspot.com/2013/05/android-layout-shadow-without-9-patch.html
(toast_frame не работает на KitKat, тень была удалена из тостов)
просто использовать:
android:background="@android:drawable/toast_frame"
или:
android:background="@android:drawable/dialog_frame"
фон
примеры:
<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" />
и с другой цвет БГ:
<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>
попробуйте это.. 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>
применить к макету, как это
android:background="@drawable/layout_shadow"
на самом деле я согласен с @odedbreiner, но я помещаю dialog_frame внутри первого слоя и скрываю черный фон под белым слоем.
<?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>
- сохранить 9.формат PNG. (измените имя на
9.png
)2.сохраните его в своем
drawable
.3.установите его в свой макет.
4.установите прокладку.
например :
<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>
создайте новый XML на примере с именем " тень.xml " в DRAWABLE со следующим кодом (вы можете изменить его или найти другой лучше):
<?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>
после создания XML в LinearLayout или другом виджете, который вы хотите создать тень, вы используете свойство BACKGROUND для просмотра эффекта. Это было бы что-то вроде :
<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">
одним из возможных решений является использование девять патч изображения, как это http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
или
Я сделал это следующим образом. Это мой основной макет, в котором round_corner.xml и drop_shadow.xml используется в качестве фонового ресурса. round_corner_two-это то же самое, что round_corner.xml только атрибут цвета отличается. скопируйте round_corner.xml, drop_shadow.xml и round_conere_two.xml в рисованная папка.
<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>
Я знаю, что это слишком поздно. но у меня было такое же требование. я решил вот так
<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>
нужно добавить зависимость:
compile 'com.android.support:cardview-v7:25.0.1'
Я знаю, что это старый, но большинство из этих ответов требует кучу дополнительного кода.
Если у вас светлый фон, вы можете просто использовать это:
android:elevation="25dp"
установите этот xml drwable в качестве фона; - - -
<?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>
вы можете использовать следующий класс для 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); } }
используйте тег в xml следующим образом:
<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>
обновление
поместите приведенный ниже код в attrs.xml в resource > > values
<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>