2010-08-25 4 views
30

Я проделал большой поиск примеров кода, но ничего не могу найти.Android Drop Shadow on View

В частности, я хочу добавить тень в png drawable, который я использую в ImageView. Этот png drawable представляет собой закругленный прямоугольник с прозрачными углами.

Может ли кто-нибудь указать пример кода, как добавить приличную тень для просмотра в код или XML?

+0

вы можете легко генерировать ninepatch тень с помощью этого инструмента http://inloop.github.io/shadow4android/ – Yuraj

ответ

29

Вы можете использовать комбинацию Bitmap.extractAlpha и BlurMaskFilter, чтобы вручную создать тень для любого изображения, которое нужно отобразить, но это будет работать только в том случае, если ваше изображение загружается или показывается только один раз, поскольку процесс дорог.

Псевдо-код (возможно, даже компилировать!):

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); 

Затем положить ShadowImage в свой ImageView. Если это изображение никогда не меняется, но отображается много, вы можете создать его и кэшировать в onCreate, чтобы обойти дорогостоящую обработку изображений.

Даже если это не работает как есть, этого должно быть достаточно, чтобы заставить вас двигаться в правильном направлении.

+3

Это своего рода работал ... После того, как я изменили offsetXY [[0] и [1] в drawBitmap как отрицательные из тех значений, которые он правильно выстроил. Однако исходное растровое изображение рисуется как сплошное черное изображение. http://cl.ly/77e6b7839c1ffc94c1e0 Как исправить? – coneybeare

+0

Не уверен, не видя код. Попробуйте проверить битдопты исходных и целевых растровых изображений. Проблема может заключаться в том, что вы рисуете 32-битное изображение (оригинал) на 8-битное изображение (извлеченный shadowImage). Если это так, сделайте что-то вроде Bitmap shadowImage32 = shadowImage.copy (ARGB_8888, true) вверх, где у меня есть комментарий для конвертации, и нарисуйте этого парня вместо 8-битного shadowImage. – Josh

+0

Здравствуйте @Josh Я использую ваш код. Его работа, но как мы можем изменить теневой цвет? –

25

Для теневого использования опускалась ниже код

<?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> 

Использование выше Drawable для фона вид

<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

Это не объяснено так хорошо, как могло бы быть, но это не совсем плохой подход. Ключевым моментом является то, что представление с градиентом в качестве фона представляет собой отдельный вид, который должен располагаться сразу под представлением, в котором вы хотите, чтобы тень отображалась. Это лучше всего работает, когда вид, который будет затенен, занимает всю ширину экрана, иначе углы будут выглядеть неправильно. –

+0

Это подход для декларативных ситуаций, но в моем случае я создаю динамическое количество кнопок в коде в зависимости от чтения данных, поэтому для моего дела это не очень полезно. – jrichview

8

Это помогло мне получить тень работать, так что я хотел бы поделиться рабочий код:

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

Для API 21 (5,0) + добавить android:elevation="4dp" или android:translationZ="4dp" для просмотра описания. Documentation

Elevation Attribute

1

Всегда использовать прозрачную тень так, чтобы они могли придерживаться любого цвета.

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> 

А Посмотреть

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