Benutzerdefinierte ImageView mit Schlagschatten

Okay, ich habe gelesen und gesucht, und ich schlage jetzt meinen Kopf gegen die Wand und versuche es herauszufinden. Hier ist was ich bisher habe

package com.pockdroid.sandbox; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.widget.ImageView; public class ShadowImageView extends ImageView { private Rect mRect; private Paint mPaint; public ShadowImageView(Context context) { super(context); mRect = new Rect(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setShadowLayer(2f, 1f, 1f, Color.BLACK); } @Override protected void onDraw(Canvas canvas) { Rect r = mRect; Paint paint = mPaint; canvas.drawRect(r, paint); super.onDraw(canvas); } @Override protected void onMeasure(int w, int h) { super.onMeasure(w,h); int mH, mW; mW = getSuggestedMinimumWidth() < getMeasuredWidth()? getMeasuredWidth() : getSuggestedMinimumWidth(); mH = getSuggestedMinimumHeight() < getMeasuredHeight()? getMeasuredHeight() : getSuggestedMinimumHeight(); setMeasuredDimension(mW + 5, mH + 5); } 

}

  • Kitkat kills: Nicht erlaubt, lokale Ressource zu laden: file: ///android_asset/webkit/android-weberror.png
  • Android: Was ist der Unterschied zwischen Activity.runOnUiThread und View.post?
  • Warum registriert IabBroadcastReceiver in Aktivität eine schlechte Idee?
  • Markieren Sie auf Clickablespan klicken
  • Holen Sie sich den String-Wert aus List <String> durch Schleife für die Anzeige
  • Android MultiDex - Fragen zu Inneren Arbeiten
  • Die "+5" in den Messungen sind da vorübergehend; Von dem, was ich verstehe, muss ich etwas Mathe machen, um die Größe zu bestimmen, die der Schlagschatten der Leinwand hinzufügt, richtig?

    Aber wenn ich das benutze:

     public View getView(int position, View convertView, ViewGroup parent) { ShadowImageView sImageView; if (convertView == null) { sImageView = new ShadowImageView(mContext); GridView.LayoutParams lp = new GridView.LayoutParams(85, 85); sImageView.setLayoutParams(lp); sImageView.setScaleType(ImageView.ScaleType.CENTER); sImageView.setPadding(5,5,5,5); } else { sImageView = (ShadowImageView) convertView; } sImageView.setImageBitmap(bitmapList.get(position)); return sImageView; } 

    In meinem ImageView bekomme ich immer noch ein normales ImageView, wenn ich das Programm laufe.

    Irgendwelche Gedanken? Vielen Dank.

    EDIT: Also sprach ich mit RomainGuy einige im IRC-Kanal, und ich habe es jetzt für einfache rechteckige Bilder mit dem untenigen Code zu arbeiten. Es wird immer noch nicht den Schatten direkt auf die Bitmap-Transparenz ziehen, also arbeite ich immer noch daran.

     @Override protected void onDraw(Canvas canvas) { Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.omen); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShadowLayer(5.5f, 6.0f, 6.0f, Color.BLACK); canvas.drawColor(Color.GRAY); canvas.drawRect(50, 50, 50 + bmp.getWidth(), 50 + bmp.getHeight(), paint); canvas.drawBitmap(bmp, 50, 50, null); } 

  • ActionBarCompat - App-Icon-Aktion (Klick) funktioniert nicht auf 4.0-Geräten
  • Import Eclipse-Projekt auf Android Studio - Fehler "dieses Projekt bezieht sich auf Eclipse Workspace ..."
  • Android Animation - Skalieren und verblassen zusammen mit Hintergrundübergang
  • Berechnen Sie die Textgröße nach der Breite des Textbereichs
  • Mehrere SearchRecentSuggestionsProvider Klassen in Android App möglich?
  • Gradle-Task-Fehler trat im Android-Studio-Projekt auf
  • 9 Solutions collect form web for “Benutzerdefinierte ImageView mit Schlagschatten”

    Okay, ich sehe nicht mehr Antworten auf diesem, so was ich am Ende ging mit jetzt ist nur eine Lösung für rechteckige Bilder. Ich habe die folgenden NinePatch verwendet:

    Alt-Text

    Zusammen mit der entsprechenden padding in XML:

     <ImageView android:id="@+id/image_test" android:background="@drawable/drop_shadow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="6px" android:paddingTop="4px" android:paddingRight="8px" android:paddingBottom="9px" android:src="@drawable/pic1" /> 

    Um ein ziemlich gutes Ergebnis zu erzielen:

    Alt-Text

    Nicht ideal, aber es wird tun.

    Das ist von Romain Guys Präsentation bei Devoxx, pdf hier gefunden.

     Paint mShadow = new Paint(); // radius=10, y-offset=2, color=black mShadow.setShadowLayer(10.0f, 0.0f, 2.0f, 0xFF000000); // in onDraw(Canvas) canvas.drawBitmap(bitmap, 0.0f, 0.0f, mShadow); 

    Hoffe das hilft.

    NOTIZEN

    1. Vergessen Sie nicht für Wabe und darüber müssen Sie setLayerType(LAYER_TYPE_SOFTWARE, mShadow) , sonst sehen Sie Ihren Schatten nicht! (@Dmitriy_Boichenko)
    2. SetShadowLayer funktioniert nicht mit Hardware-Beschleunigung leider, so dass es erheblich reduziert Performances (@Matt Wear) [1] [2]

    Ich glaube diese Antwort von UIFuel

     <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Drop Shadow Stack --> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#00CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#10CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#20CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#30CCCCCC" /> </shape> </item> <item> <shape> <padding android:top="1dp" android:right="1dp" android:bottom="1dp" android:left="1dp" /> <solid android:color="#50CCCCCC" /> </shape> </item> <!-- Background --> <item> <shape> <solid android:color="@color/white" /> <corners android:radius="3dp" /> </shape> </item> </layer-list> 

    Meine schmutzige Lösung:

     private static Bitmap getDropShadow3(Bitmap bitmap) { if (bitmap==null) return null; int think = 6; int w = bitmap.getWidth(); int h = bitmap.getHeight(); int newW = w - (think); int newH = h - (think); Bitmap.Config conf = Bitmap.Config.ARGB_8888; Bitmap bmp = Bitmap.createBitmap(w, h, conf); Bitmap sbmp = Bitmap.createScaledBitmap(bitmap, newW, newH, false); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Canvas c = new Canvas(bmp); // Right Shader rshader = new LinearGradient(newW, 0, w, 0, Color.GRAY, Color.LTGRAY, Shader.TileMode.CLAMP); paint.setShader(rshader); c.drawRect(newW, think, w, newH, paint); // Bottom Shader bshader = new LinearGradient(0, newH, 0, h, Color.GRAY, Color.LTGRAY, Shader.TileMode.CLAMP); paint.setShader(bshader); c.drawRect(think, newH, newW , h, paint); //Corner Shader cchader = new LinearGradient(0, newH, 0, h, Color.LTGRAY, Color.LTGRAY, Shader.TileMode.CLAMP); paint.setShader(cchader); c.drawRect(newW, newH, w , h, paint); c.drawBitmap(sbmp, 0, 0, null); return bmp; } 

    Ergebnis: Bildbeschreibung hier eingeben

    Hier sind Sie ja. Setzen Sie die Quelle von ImageView statisch in xml oder dynamisch in Code.

    Schatten ist hier weiß.

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <View android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/white" android:layout_alignLeft="@+id/image" android:layout_alignRight="@id/image" android:layout_alignTop="@id/image" android:layout_alignBottom="@id/image" android:layout_marginLeft="10dp" android:layout_marginBottom="10dp" /> <ImageView android:id="@id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="..." android:padding="5dp" /> </RelativeLayout> 

    Ich schaffe es, Gradientenrand mit diesem Code anzuwenden ..

     public static Bitmap drawShadow(Bitmap bitmap, int leftRightThk, int bottomThk, int padTop) { int w = bitmap.getWidth(); int h = bitmap.getHeight(); int newW = w - (leftRightThk * 2); int newH = h - (bottomThk + padTop); Bitmap.Config conf = Bitmap.Config.ARGB_8888; Bitmap bmp = Bitmap.createBitmap(w, h, conf); Bitmap sbmp = Bitmap.createScaledBitmap(bitmap, newW, newH, false); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Canvas c = new Canvas(bmp); // Left int leftMargin = (leftRightThk + 7)/2; Shader lshader = new LinearGradient(0, 0, leftMargin, 0, Color.TRANSPARENT, Color.BLACK, TileMode.CLAMP); paint.setShader(lshader); c.drawRect(0, padTop, leftMargin, newH, paint); // Right Shader rshader = new LinearGradient(w - leftMargin, 0, w, 0, Color.BLACK, Color.TRANSPARENT, TileMode.CLAMP); paint.setShader(rshader); c.drawRect(newW, padTop, w, newH, paint); // Bottom Shader bshader = new LinearGradient(0, newH, 0, bitmap.getHeight(), Color.BLACK, Color.TRANSPARENT, TileMode.CLAMP); paint.setShader(bshader); c.drawRect(leftMargin -3, newH, newW + leftMargin + 3, bitmap.getHeight(), paint); c.drawBitmap(sbmp, leftRightThk, 0, null); return bmp; } 

    hoffe das hilft !

    Das funktioniert für mich …

     public class ShadowImage extends Drawable { Bitmap bm; @Override public void draw(Canvas canvas) { Paint mShadow = new Paint(); Rect rect = new Rect(0,0,bm.getWidth(), bm.getHeight()); mShadow.setAntiAlias(true); mShadow.setShadowLayer(5.5f, 4.0f, 4.0f, Color.BLACK); canvas.drawRect(rect, mShadow); canvas.drawBitmap(bm, 0.0f, 0.0f, null); } public ShadowImage(Bitmap bitmap) { super(); this.bm = bitmap; } ... } 

    Hier die Umsetzung von Paul Burke s Antwort:

     public class ShadowImageView extends ImageView { public ShadowImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ShadowImageView(Context context, AttributeSet attrs) { super(context, attrs); } public ShadowImageView(Context context) { super(context); } private Paint createShadow() { Paint mShadow = new Paint(); float radius = 10.0f; float xOffset = 0.0f; float yOffset = 2.0f; // color=black int color = 0xFF000000; mShadow.setShadowLayer(radius, xOffset, yOffset, color); return mShadow; } @Override protected void onDraw(Canvas canvas) { Paint mShadow = createShadow(); Drawable d = getDrawable(); if (d != null){ setLayerType(LAYER_TYPE_SOFTWARE, mShadow); Bitmap bitmap = ((BitmapDrawable) getDrawable()).getBitmap(); canvas.drawBitmap(bitmap, 0.0f, 0.0f, mShadow); } else { super.onDraw(canvas); } }; } 

    TODO: setLayerType(LAYER_TYPE_SOFTWARE, mShadow); ausführen setLayerType(LAYER_TYPE_SOFTWARE, mShadow); Nur wenn API Level> 10 ist

    Ich habe auf die Antwort oben gebaut – https://stackoverflow.com/a/11155031/2060486 – um einen Schatten um alle Seiten zu schaffen ..

      private static final int GRAY_COLOR_FOR_SHADE = Color.argb(50, 79, 79, 79); // this method takes a bitmap and draws around it 4 rectangles with gradient to create a // shadow effect. public static Bitmap addShadowToBitmap(Bitmap origBitmap) { int shadowThickness = 13; // can be adjusted as needed int bmpOriginalWidth = origBitmap.getWidth(); int bmpOriginalHeight = origBitmap.getHeight(); int bigW = bmpOriginalWidth + shadowThickness * 2; // getting dimensions for a bigger bitmap with margins int bigH = bmpOriginalHeight + shadowThickness * 2; Bitmap containerBitmap = Bitmap.createBitmap(bigW, bigH, Bitmap.Config.ARGB_8888); Bitmap copyOfOrigBitmap = Bitmap.createScaledBitmap(origBitmap, bmpOriginalWidth, bmpOriginalHeight, false); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Canvas canvas = new Canvas(containerBitmap); // drawing the shades on the bigger bitmap //right shade - direction of gradient is positive x (width) Shader rightShader = new LinearGradient(bmpOriginalWidth, 0, bigW, 0, GRAY_COLOR_FOR_SHADE, Color.TRANSPARENT, Shader.TileMode.CLAMP); paint.setShader(rightShader); canvas.drawRect(bigW - shadowThickness, shadowThickness, bigW, bigH - shadowThickness, paint); //bottom shade - direction is positive y (height) Shader bottomShader = new LinearGradient(0, bmpOriginalHeight, 0, bigH, GRAY_COLOR_FOR_SHADE, Color.TRANSPARENT, Shader.TileMode.CLAMP); paint.setShader(bottomShader); canvas.drawRect(shadowThickness, bigH - shadowThickness, bigW - shadowThickness, bigH, paint); //left shade - direction is negative x Shader leftShader = new LinearGradient(shadowThickness, 0, 0, 0, GRAY_COLOR_FOR_SHADE, Color.TRANSPARENT, Shader.TileMode.CLAMP); paint.setShader(leftShader); canvas.drawRect(0, shadowThickness, shadowThickness, bigH - shadowThickness, paint); //top shade - direction is negative y Shader topShader = new LinearGradient(0, shadowThickness, 0, 0, GRAY_COLOR_FOR_SHADE, Color.TRANSPARENT, Shader.TileMode.CLAMP); paint.setShader(topShader); canvas.drawRect(shadowThickness, 0, bigW - shadowThickness, shadowThickness, paint); // starting to draw bitmap not from 0,0 to get margins for shade rectangles canvas.drawBitmap(copyOfOrigBitmap, shadowThickness, shadowThickness, null); return containerBitmap; } 

    Ändern Sie die Farbe in der const, wie Sie sehen, passen.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.