Jak mogę pokazać cień dla mojego układu liniowego. Chcę mieć zaokrąglone tło w kolorze białym z cieniem wokół układu liniowego. Jak dotąd robiłem to.
<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>
I rounded_rect_shape.xml w katalogu 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>
Odpowiedzi:
W Androidzie nie ma takiego atrybutu, aby pokazać cień. Ale możliwe sposoby to:
Dodaj zwykły układ LinearLayout z szarym kolorem, nad którym dodaj rzeczywisty układ, z marginesami na dole i po prawej stronie równymi 1 lub 2 dp
Zrób 9-punktowy obraz z cieniem i ustaw go jako tło dla swojego układu liniowego
źródło
Istnieje również inne rozwiązanie problemu poprzez zaimplementowanie listy warstw, która będzie działać jako tło dla LinearLayoout.
Dodaj plik background_with_shadow.xml do
res/drawable
. Zawierający:<?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>
Następnie dodaj listę warstw jako tło w swoim LinearLayout.
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/background_with_shadow"/>
źródło
Cóż, jest to łatwe do osiągnięcia.
Po prostu zbuduj,
GradientDrawable
który pochodzi z czerni i przejdzie do przezroczystego koloru, niż użyj relacji nadrzędnej, aby umieścić swój kształt blisko widoku, w którym chcesz mieć cień, a następnie musisz podać dowolne wartości wysokości lub szerokości.Oto przykład, ten plik musi być utworzony w środku
res/drawable
, nazywam goshadow.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>
Umieść poniższy kod powyżej z a
LinearLayout
, na przykład ustawandroid:layout_width
iandroid:layout_height
na,fill_parent
a2.3dp
uzyskasz ładny efekt cienia naLinearLayout
.<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>
Uwaga 1: Jeśli zwiększysz
android:layout_height
więcej cienia, pojawi się.Uwaga 2: Użyj
android:layout_above="@+id/id_from_your_LinearLayout"
atrybutu, jeśli umieszczasz ten kod wewnątrz RelativeLayout, w przeciwnym razie zignoruj go.Mam nadzieję, że to komuś pomoże.
źródło
W przypadku Lollipopa i wyższych można użyć elewacji .
W przypadku starszych wersji:
Oto leniwy hack z: http://odedhb.blogspot.com/2013/05/android-layout-shadow-without-9-patch.html
(toast_frame nie działa na KitKat, cień został usunięty z toastów)
po prostu użyj:
android:background="@android:drawable/toast_frame"
lub:
android:background="@android:drawable/dialog_frame"
jako tło
przykłady:
<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" />
iz innym kolorem 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>
źródło
android:background="@android:drawable/alert_light_frame"
dla białychSpróbuj tego ... 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>
Zastosuj do swojego układu w ten sposób
android:background="@drawable/layout_shadow"
źródło
Wiem, że to stare, ale większość tych odpowiedzi wymaga mnóstwa dodatkowego kodu.
Jeśli masz jasne tło, możesz po prostu użyć tego:
android:elevation="25dp"
źródło
Właściwie zgadzam się z @odedbreiner, ale umieszczam ramkę dialogową wewnątrz pierwszej warstwy i ukrywam czarne tło pod białą warstwą.
<?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>
źródło
9.png
)2. zapisz go w swoim
drawable
.3. ustaw go zgodnie z układem.
4. zestaw wyściółki.
Na przykład :
<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>
źródło
Utwórz nowy XML na przykładzie o nazwie „shadow.xml” w DRAWABLE z następującym kodem (możesz go zmodyfikować lub znaleźć inny lepszy):
<?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>
Po utworzeniu XML w LinearLayout lub innym widżecie, który chcesz utworzyć odcień, użyj właściwości BACKGROUND, aby zobaczyć efekt. To byłoby coś takiego:
<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">
źródło
Możesz użyć następującej klasy dla tagu 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); } }
użyj tagu w XML w następujący sposób:
<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>
AKTUALIZACJA
umieść poniższy kod w attrs.xml w 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>
źródło
<TextView>
, wyśrodkowałem TextView, ale nie dodałem cienia.Jednym z możliwych rozwiązań jest użycie dziewięciu obrazów łatek, takich jak ten http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch
LUB
Zrobiłem to w następujący sposób. To jest mój główny układ, w którym round_corner.xml i drop_shadow.xml są używane jako zasoby tła. round_corner_two jest taki sam jak round_corner.xml, tylko atrybut koloru jest inny. skopiuj pliki round_corner.xml, drop_shadow.xml i round_conere_two.xml do folderu do rysowania.
<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>
źródło
wiem, że to już za późno. ale miałem te same wymagania. rozwiązałem w ten sposób
<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>
musisz dodać zależność:
compile 'com.android.support:cardview-v7:25.0.1'
źródło
ustaw ten plik XML jako tło; ---
<?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>
źródło