studio programacion herramientas fundamentos con avanzado aplicaciones java android imageview

java - programacion - manual de android en pdf



Cómo agregar una sombra y un borde en imageView circular Android? (7)

Creé un CircularImageView con esta pregunta: Crear vista de imagen circular en Android

Descargar proyecto en GitHub

1) Esta es la clase CircularImageView:

public class CircularImageView extends ImageView { public CircularImageView(Context context) { super(context); } public CircularImageView(Context context, AttributeSet attrs) { super(context, attrs); } public CircularImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { Drawable drawable = getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } Bitmap b = ((BitmapDrawable)drawable).getBitmap() ; Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); Bitmap roundBitmap = getCroppedBitmap(bitmap, getWidth()); canvas.drawBitmap(roundBitmap, 0, 0, null); } public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) { Bitmap sbmp; if(bmp.getWidth() != radius || bmp.getHeight() != radius) sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false); else sbmp = bmp; Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(), Bitmap.Config.ARGB_8888); final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight()); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); paint.setColor(Color.parseColor("#BAB399")); Canvas c = new Canvas(output); c.drawARGB(0, 0, 0, 0); c.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f, sbmp.getWidth() / 2+0.1f, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); c.drawBitmap(sbmp, rect, rect, paint); return output; } }

2) Uso en mi diseño de esta manera:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#cccccc" android:gravity="center" android:orientation="vertical" android:padding="10dp" > <com.mikhaellopez.circularimageview.CircularImageView android:id="@+id/imageViewCircular" android:layout_width="@dimen/image_view_size" android:layout_height="@dimen/image_view_size" android:layout_gravity="center" android:background="@drawable/border" android:src="@drawable/image" /> </LinearLayout>

3) resultado actual en la imagen:

¿Cómo cambio este código para tener una sombra y un borde circular alrededor de mi imageView?

Resultado Objectif:

Editar 15/10/2015:

Puede utilizar o descargar mi biblioteca GitHub GitHub con todas las correcciones usando la dependencia gradle :

compile ''com.mikhaellopez:circularimageview:2.0.1''


  1. Añada canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, paint); antes de canvas.drawBitmap(roundBitmap, 0, 0, null);
  2. Cambie c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2, paint); a c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2 - "the border with you prefer", paint);

Espero eso ayude.

Quizás una mejor solución aquí .




Esta clase es una vista de imagen circular personalizada con sombra, trazo, saturación y con esta vista circular de imagen personalizada puede hacer que su imagen tenga forma circular con radio. Chicos para Circular Shadow ImageView No es necesario Github esta clase es suficiente.

Agregar CircularImageView a su diseño

// Bitmap myimage = BitmapFactory.decodeResource (getResources (), R.drawable.pic); CircularImageView c = new CircularImageView (esto, ancho de pantalla, altura de pantalla, myimage Bitmap); yourLayout.addView (c); **

public class CircularImageView extends android.support.v7.widget.AppCompatImageView { private final Context context; private final int width, height; private final Paint paint; private final Paint paintBorder,imagePaint; private final Bitmap bitmap2; private final Paint paint3; private Bitmap bitmap; private BitmapShader shader; private float radius = 4.0f; float x = 0.0f; float y = 8.0f; private float stroke; private float strokeWidth = 0.0f; private Bitmap bitmap3; private int corner_radius=50; public CircularImageView(Context context, int width, int height, Bitmap bitmap) { super(context); this.context = context; this.width = width; this.height = height; //here "bitmap" is the square shape(width* width) scaled bitmap .. this.bitmap = bitmap; paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); paint3=new Paint(); paint3.setStyle(Paint.Style.STROKE); paint3.setColor(Color.WHITE); paint3.setAntiAlias(true); paintBorder = new Paint(); imagePaint= new Paint(); paintBorder.setColor(Color.WHITE); paintBorder.setAntiAlias(true); this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); this.bitmap2 = Bitmap.createScaledBitmap(bitmap, (bitmap.getWidth() - 40), (bitmap.getHeight() - 40), true); imagePaint.setAntiAlias(true); invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Shader b; if (bitmap3 != null) b = new BitmapShader(bitmap3, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); else b = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); imagePaint.setShader(b); canvas.drawBitmap(maskedBitmap(), 20, 20, null); } private Bitmap maskedBitmap() { Bitmap l1 = Bitmap.createBitmap(width,width, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(l1); paintBorder.setShadowLayer(radius, x, y, Color.parseColor("#454645")); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); final RectF rect = new RectF(); rect.set(20, 20, bitmap2.getWidth(), bitmap2.getHeight()); canvas.drawRoundRect(rect, corner_radius, corner_radius, paintBorder); canvas.drawRoundRect(rect, corner_radius, corner_radius, imagePaint); if (strokeWidth!=0.0f) { paint3.setStrokeWidth(strokeWidth); canvas.drawRoundRect(rect, corner_radius, corner_radius, paint3); } paint.setXfermode(null); return l1; } // use seekbar here, here you have to pass "0 -- 250" here corner radius will change public void setCornerRadius(int corner_radius) { this.corner_radius = corner_radius; invalidate(); } -------->use seekbar here, here you have to pass "0 -- 10.0f" here shadow radius will change public void setShadow(float radius) { this.radius = radius; invalidate(); } // use seekbar here, here you have to pass "0 -- 10.0f" here stroke size will change public void setStroke(float stroke) { this.strokeWidth = stroke; invalidate(); } private Bitmap updateSat(Bitmap src, float settingSat) { int w = src.getWidth(); int h = src.getHeight(); Bitmap bitmapResult = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvasResult = new Canvas(bitmapResult); Paint paint = new Paint(); ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.setSaturation(settingSat); ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix); paint.setColorFilter(filter); canvasResult.drawBitmap(src, 0, 0, paint); return bitmapResult; } // use seekbar here, here you have to pass "0 -- 2.0f" here saturation will change public void setSaturation(float sat) { System.out.println("qqqqqqqqqq "+sat); bitmap3=updateSat(bitmap2, sat); invalidate(); } } // Seekbar to change radius radius_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { text_radius.setText(""+progress); circularImageView.setCornerRadius(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); // Seekbar to change shadow shadow_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { float f= 4+progress/10.0f; text_shadow.setText(""+progress); circularImageView.setShadow(f); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); // Seekbar to change saturation saturation_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int progressSat = saturation_seekbar.getProgress(); float sat = (float) ((progressSat*4 / 100.0f)-1.0f); circularImageView.setSaturation(sat); text_saturation.setText(""+progressSat); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); // Seekbar to change stroke stroke_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (progress==0) { float f=(progress*10.0f/100.0f); circularImageView.setStroke(f); } else { float f=(progress*10.0f/100.0f); circularImageView.setStroke(f); } text_stroke.setText(""+progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); //radius seekbar in xml file <SeekBar android:layout_width="match_parent" android:layout_gravity="center" android:progress="50" android:max="250" android:id="@+id/radius_seekbar" android:layout_height="wrap_content" /> //saturation seekbar in xml file <SeekBar android:layout_width="match_parent" android:layout_gravity="center" android:progress="50" android:max="100" android:id="@+id/saturation_seekbar" android:layout_height="wrap_content" /> //shadow seekbar in xml file <SeekBar android:layout_width="match_parent" android:layout_gravity="center" android:progress="0" android:max="100" android:id="@+id/shadow_seekbar" android:layout_height="wrap_content" /> //stroke seekbar in xml file <SeekBar android:layout_width="match_parent" android:layout_gravity="center" android:progress="0" android:max="100" android:id="@+id/stroke _seekbar" android:layout_height="wrap_content" />


Modifiqué la CircularImageView que se encuentra aquí para lograr lo que quieres.

Para crear una sombra alrededor del borde, simplemente usé estas dos líneas:

this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);

Necesita setLayerType debido a la aceleración de hardware en HoneyComb y superior. No funcionó sin eso cuando lo probé.

Aquí está el código completo:

import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.util.AttributeSet; import android.widget.ImageView; public class CircularImageView extends ImageView { private int borderWidth = 4; private int viewWidth; private int viewHeight; private Bitmap image; private Paint paint; private Paint paintBorder; private BitmapShader shader; public CircularImageView(Context context) { super(context); setup(); } public CircularImageView(Context context, AttributeSet attrs) { super(context, attrs); setup(); } public CircularImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setup(); } private void setup() { // init paint paint = new Paint(); paint.setAntiAlias(true); paintBorder = new Paint(); setBorderColor(Color.WHITE); paintBorder.setAntiAlias(true); this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK); } public void setBorderWidth(int borderWidth) { this.borderWidth = borderWidth; this.invalidate(); } public void setBorderColor(int borderColor) { if (paintBorder != null) paintBorder.setColor(borderColor); this.invalidate(); } private void loadBitmap() { BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable(); if (bitmapDrawable != null) image = bitmapDrawable.getBitmap(); } @SuppressLint("DrawAllocation") @Override public void onDraw(Canvas canvas) { // load the bitmap loadBitmap(); // init shader if (image != null) { shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); paint.setShader(shader); int circleCenter = viewWidth / 2; // circleCenter is the x or y of the view''s center // radius is the radius in pixels of the cirle to be drawn // paint contains the shader that will texture the shape canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder); canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, paint); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(widthMeasureSpec); int height = measureHeight(heightMeasureSpec, widthMeasureSpec); viewWidth = width - (borderWidth * 2); viewHeight = height - (borderWidth * 2); setMeasuredDimension(width, height); } private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text result = viewWidth; } return result; } private int measureHeight(int measureSpecHeight, int measureSpecWidth) { int result = 0; int specMode = MeasureSpec.getMode(measureSpecHeight); int specSize = MeasureSpec.getSize(measureSpecHeight); if (specMode == MeasureSpec.EXACTLY) { // We were told how big to be result = specSize; } else { // Measure the text (beware: ascent is a negative number) result = viewHeight; } return (result + 2); } }

¡Espero que ayude!

.

EDITAR

Bifurqué su CircularImageView y agregué soporte para superposiciones de selector. También mejoré el rendimiento del dibujo significativamente ...

https://github.com/Pkmmte/CircularImageView


Para agregar un borde haciendo ImageView como un círculo, he hecho algo simple, utilicé esta clase para hacer que mi imagen sea un círculo

package com.fidenz.fexceller.fexceller; /** * Created by Chathu Hettiarachchi on 5/18/2015. */ import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.Drawable; public class RoundedImg extends Drawable { private final Bitmap mBitmap; private final Paint mPaint; private final RectF mRectF; private final int mBitmapWidth; private final int mBitmapHeight; public RoundedImg(Bitmap bitmap) { mBitmap = bitmap; mRectF = new RectF(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setShader(shader); mBitmapWidth = mBitmap.getWidth(); mBitmapHeight = mBitmap.getHeight(); } @Override public void draw(Canvas canvas) { canvas.drawOval(mRectF, mPaint); } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mRectF.set(bounds); } @Override public void setAlpha(int alpha) { if (mPaint.getAlpha() != alpha) { mPaint.setAlpha(alpha); invalidateSelf(); } } @Override public void setColorFilter(ColorFilter cf) { mPaint.setColorFilter(cf); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } @Override public int getIntrinsicWidth() { return mBitmapWidth; } @Override public int getIntrinsicHeight() { return mBitmapHeight; } public void setAntiAlias(boolean aa) { mPaint.setAntiAlias(aa); invalidateSelf(); } @Override public void setFilterBitmap(boolean filter) { mPaint.setFilterBitmap(filter); invalidateSelf(); } @Override public void setDither(boolean dither) { mPaint.setDither(dither); invalidateSelf(); } public Bitmap getBitmap() { return mBitmap; } }

y al usar esto en onCreate he llamado a la imagen para configurarlo,

profilePic = (ImageView)findViewById(R.id.img_home_profile_pic); Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.no_image); roundedImage = new RoundedImg(bm); profilePic.setImageDrawable(roundedImage);

para agregar un borde, creé un XML de forma de círculo como este,

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <gradient android:startColor="@color/ring_color" android:endColor="@color/ring_color" android:angle="270"/> </shape>

Luego, usando diseños, agregué un RelativeLayout con ImageView dentro de él, usando relleno y fondo wrap_content con wrap_content . Establecí mi RelativeLayout como este

<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/lay_rel_img" android:layout_gravity="center" android:padding="5dp" android:background="@drawable/circle"> <ImageView android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center" android:id="@+id/img_home_profile_pic" android:src="@drawable/no_image" android:layout_centerHorizontal="true"/> </RelativeLayout>

ahora se muestra así, no sé agregar la sombra, lo siento por eso también


simplemente use el método drawCircle () con más ancho y alto antes de dibujar la imagen real. Aumente el ancho y alto de esa nueva llamada de método de acuerdo con su deseo, y configure otro color que desee en la pintura