studio redondeadas redonda imagen hacer esquinas circleimageview android imageview android-imageview android-image rounded-corners

redonda - esquinas redondeadas android studio



¿Cómo hacer un ImageView con esquinas redondeadas? (30)

En Android, un ImageView es un rectángulo por defecto. ¿Cómo puedo convertirlo en un rectángulo redondeado (recorte las 4 esquinas de mi mapa de bits para que sean rectángulos redondeados) en el ImageView?


Apoyos a George Walters II en la parte superior, tomé su respuesta y la extendí un poco para apoyar las esquinas individuales de forma diferente. Esto podría optimizarse un poco más (algunos de los rects de destino se superponen), pero no mucho.

Sé que este hilo es un poco antiguo, pero es uno de los mejores resultados para las consultas en Google sobre cómo redondear las esquinas de ImageViews en Android.

/** * Use this method to scale a bitmap and give it specific rounded corners. * @param context Context object used to ascertain display density. * @param bitmap The original bitmap that will be scaled and have rounded corners applied to it. * @param upperLeft Corner radius for upper left. * @param upperRight Corner radius for upper right. * @param lowerRight Corner radius for lower right. * @param lowerLeft Corner radius for lower left. * @param endWidth Width to which to scale original bitmap. * @param endHeight Height to which to scale original bitmap. * @return Scaled bitmap with rounded corners. */ public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft, float upperRight, float lowerRight, float lowerLeft, int endWidth, int endHeight) { float densityMultiplier = context.getResources().getDisplayMetrics().density; // scale incoming bitmap to appropriate px size given arguments and display dpi bitmap = Bitmap.createScaledBitmap(bitmap, Math.round(endWidth * densityMultiplier), Math.round(endHeight * densityMultiplier), true); // create empty bitmap for drawing Bitmap output = Bitmap.createBitmap( Math.round(endWidth * densityMultiplier), Math.round(endHeight * densityMultiplier), Config.ARGB_8888); // get canvas for empty bitmap Canvas canvas = new Canvas(output); int width = canvas.getWidth(); int height = canvas.getHeight(); // scale the rounded corners appropriately given dpi upperLeft *= densityMultiplier; upperRight *= densityMultiplier; lowerRight *= densityMultiplier; lowerLeft *= densityMultiplier; Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); // fill the canvas with transparency canvas.drawARGB(0, 0, 0, 0); // draw the rounded corners around the image rect. clockwise, starting in upper left. canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint); canvas.drawCircle(width - upperRight, upperRight, upperRight, paint); canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint); canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint); // fill in all the gaps between circles. clockwise, starting at top. RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2); RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight); RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height); RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft); canvas.drawRect(rectT, paint); canvas.drawRect(rectR, paint); canvas.drawRect(rectB, paint); canvas.drawRect(rectL, paint); // set up the rect for the image Rect imageRect = new Rect(0, 0, width, height); // set up paint object such that it only paints on Color.WHITE paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET)); // draw resized bitmap onto imageRect in canvas, using paint as configured above canvas.drawBitmap(bitmap, imageRect, imageRect, paint); return output; }


Como todas las respuestas me parecieron demasiado complicadas para las esquinas redondeadas, pensé y encontré otra solución que creo que vale la pena compartir, solo con XML en caso de que tenga algo de espacio alrededor de la imagen:

Crea una forma bordeada con contenido transparente como este:

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="30dp" /> <stroke android:color="#ffffffff" android:width="10dp" /> </shape>

Luego, en un RelativeLayout, primero puede colocar su imagen y luego en la misma ubicación sobre la forma con otro ImageView. La forma de la cubierta debe ser más grande en tamaño por la cantidad del ancho del borde. Tenga cuidado de tomar un radio de esquina más grande ya que el radio exterior está definido, pero el radio interior es lo que cubre su imagen.

Espero que también ayude a alguien.

Edite según solicitud de CQM el ejemplo de diseño relativo:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/imageToShow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/imgCorners" android:layout_alignLeft="@+id/imgCorners" android:layout_alignRight="@+id/imgCorners" android:layout_alignTop="@+id/imgCorners" android:background="#ffffff" android:contentDescription="@string/desc" android:padding="5dp" android:scaleType="centerCrop" /> <ImageView android:id="@+id/imgCorners" android:layout_width="wrap_content" android:layout_height="wrap_content" android:adjustViewBounds="true" android:contentDescription="@string/desc" android:src="@drawable/corners_white" /> </RelativeLayout>


Debes extender ImageView y dibujar tu propio rectángulo redondeado.

Si desea un marco alrededor de la imagen, también puede superponer el marco redondeado en la parte superior de la vista de la imagen en el diseño.

[editar] Superponga el marco en op la imagen original, usando un FrameLayout por ejemplo. El primer elemento de FrameLayout será la imagen que desea mostrar redondeada. A continuación, agregue otro ImageView con el marco. El segundo ImageView se mostrará sobre el ImageView original y, por lo tanto, Android dibujará su contenido sobre el ImageView .


El recorte a formas redondeadas se agregó a la clase de View en API 21.

Solo haz esto:

  • Crea una forma redondeada dibujable, algo como esto:

res / drawable / round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="10dp" /> ... </shape>

  • Establezca el dibujo como fondo de su ImageView: android:background="@drawable/round_outline"
  • De acuerdo con esta documentation , todo lo que necesita hacer es agregar android:clipToOutline="true"

Desafortunadamente, hay un error y ese atributo XML no se reconoce. Afortunadamente, todavía podemos configurar el recorte en Java:

  • En su actividad o fragmento: ImageView.setClipToOutline(true)

Esto es lo que se verá:

Nota:

Este método funciona para cualquier forma dibujable (no solo redondeada). Recortará el ImageView a cualquier contorno de forma que haya definido en su xml Drawable.

Nota especial sobre ImageViews

setClipToOutline() solo funciona cuando el fondo de la Vista se establece en una forma dibujable. Si esta forma de fondo existe, la vista trata el contorno de la forma como los bordes para fines de recorte y sombreado.

Esto significa que, si desea usar setClipToOutline() para redondear las esquinas en un ImageView, su imagen debe configurarse con android:src lugar de android:background (ya que background debe configurarse en su forma redondeada). Si DEBE usar el fondo para establecer su imagen en lugar de src, puede usar esta solución:

  • Crea un diseño y establece su fondo a tu forma dibujable
  • Envuelva ese diseño alrededor de su ImageView (sin relleno)
  • La vista de imagen (incluyendo cualquier otra cosa en el diseño) ahora se mostrará con una forma de diseño redondeada.

En la v21 de la biblioteca de soporte ahora hay una solución para esto: se llama RoundedBitmapDrawable .

Básicamente es como un Drawable normal, excepto que le das un radio de esquina para el recorte con:

setCornerRadius(float cornerRadius)

Entonces, comenzando con Bitmap src y un ImageView destino, se vería algo así:

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src); dr.setCornerRadius(cornerRadius); imageView.setImageDrawable(dr);


Encontré que ambos métodos fueron muy útiles para encontrar una solución de trabajo. Aquí está mi versión compuesta, que es independiente de píxeles y le permite tener algunas esquinas cuadradas con el resto de las esquinas que tienen el mismo radio (que es el caso de uso habitual). Gracias a las dos soluciones anteriores:

public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR ) { Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888); Canvas canvas = new Canvas(output); final float densityMultiplier = context.getResources().getDisplayMetrics().density; final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, w, h); final RectF rectF = new RectF(rect); //make sure that our rounded corner is scaled appropriately final float roundPx = pixels*densityMultiplier; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); //draw rectangles over the corners we want to be square if (squareTL ){ canvas.drawRect(0, h/2, w/2, h, paint); } if (squareTR ){ canvas.drawRect(w/2, h/2, w, h, paint); } if (squareBL ){ canvas.drawRect(0, 0, w/2, h/2, paint); } if (squareBR ){ canvas.drawRect(w/2, 0, w, h/2, paint); } paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(input, 0,0, paint); return output; }

Además, anulé ImageView para poner esto de modo que pudiera definirlo en xml. Es posible que desee agregar algo de la lógica que hace la súper llamada aquí, pero lo he comentado ya que no es útil en mi caso.

@Override protected void onDraw(Canvas canvas) { //super.onDraw(canvas); Drawable drawable = getDrawable(); Bitmap b = ((BitmapDrawable)drawable).getBitmap() ; Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); int w = getWidth(), h = getHeight(); Bitmap roundBitmap = CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false); canvas.drawBitmap(roundBitmap, 0,0 , null); }

¡Espero que esto ayude!


Esta solución xml pura fue lo suficientemente buena en mi caso. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

EDITAR

Aquí está la respuesta en pocas palabras:

En la carpeta / res / drawable, cree un archivo frame.xml. En ella, definimos un rectángulo simple con esquinas redondeadas y un centro transparente .

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#00ffffff" /> <padding android:left="6dp" android:top="6dp" android:right="6dp" android:bottom="6dp" /> <corners android:radius="12dp" /> <stroke android:width="6dp" android:color="#ffffffff" /> </shape>

En el archivo de diseño, agrega un LinearLayout que contiene un ImageView estándar, así como un FrameLayout anidado. FrameLayout utiliza el relleno y el dibujo personalizable para dar la ilusión de esquinas redondeadas.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:layout_gravity="center" android:gravity="center" android:background="#ffffffff"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="6dp" android:src="@drawable/tr"/> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:padding="6dp" android:src="@drawable/tr"/> <ImageView android:src="@drawable/frame" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> </LinearLayout>


Imagen redondeada usando ImageLoader here

Crear DisplayImageOptions :

DisplayImageOptions options = new DisplayImageOptions.Builder() // this will make circle, pass the width of image .displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu))) .cacheOnDisc(true) .build(); imageLoader.displayImage(url_for_image,ImageView,options);

O puedes usar la Biblioteca Picasso desde la Plaza.

Picasso.with(mContext) .load(com.app.utility.Constants.BASE_URL+b.image) .placeholder(R.drawable.profile) .error(R.drawable.profile) .transform(new RoundedTransformation(50, 4)) .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size) .centerCrop() .into(v.im_user);

Puede descargar el archivo RoundedTransformation aquí here


La respuesta es bastante tardía, pero para cualquier otra persona que esté buscando esto, puede hacer el siguiente código para redondear manualmente las esquinas de sus imágenes.

http://www.ruibm.com/?p=184

Este no es mi código, pero lo he usado y funciona de maravilla. Lo usé como ayudante dentro de una clase de ImageHelper y lo extendí solo un poco para pasar la cantidad de plumaje que necesito para una imagen determinada.

El código final se ve así:

package com.company.app.utils; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Bitmap.Config; import android.graphics.PorterDuff.Mode; public class ImageHelper { public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap .getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(output); final int color = 0xff424242; final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } }

¡Espero que esto ayude a alguien!


Lo he hecho por Custom ImageView:

public class RoundRectCornerImageView extends ImageView { private float radius = 18.0f; private Path path; private RectF rect; public RoundRectCornerImageView(Context context) { super(context); init(); } public RoundRectCornerImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RoundRectCornerImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { path = new Path(); } @Override protected void onDraw(Canvas canvas) { rect = new RectF(0, 0, this.getWidth(), this.getHeight()); path.addRoundRect(rect, radius, radius, Path.Direction.CW); canvas.clipPath(path); super.onDraw(canvas); } }

Cómo utilizar:

<com.mypackage.RoundRectCornerImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/image" android:scaleType="fitXY" />

Salida:

Espero que esto te ayude.


Mi implementación de ImageView con el widget de esquinas redondeadas, que (abajo || arriba) ajusta la imagen a las dimensiones requeridas. Utiliza el código de CaspNZ.

public class ImageViewRounded extends ImageView { public ImageViewRounded(Context context) { super(context); } public ImageViewRounded(Context context, AttributeSet attrs) { super(context, attrs); } public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { BitmapDrawable drawable = (BitmapDrawable) getDrawable(); if (drawable == null) { return; } if (getWidth() == 0 || getHeight() == 0) { return; } Bitmap fullSizeBitmap = drawable.getBitmap(); int scaledWidth = getMeasuredWidth(); int scaledHeight = getMeasuredHeight(); Bitmap mScaledBitmap; if (scaledWidth == fullSizeBitmap.getWidth() && scaledHeight == fullSizeBitmap.getHeight()) { mScaledBitmap = fullSizeBitmap; } else { mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap, scaledWidth, scaledHeight, true /* filter */); } Bitmap roundBitmap = ImageUtilities.getRoundedCornerBitmap(getContext(), mScaledBitmap, 5, scaledWidth, scaledHeight, false, false, false, false); canvas.drawBitmap(roundBitmap, 0, 0, null); } }


Otra forma fácil es usar un CardView con el radio de la esquina y un ImageView dentro:

<android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="match_parent" app:cardCornerRadius="8dp" android:layout_margin="5dp" android:elevation="10dp"> <ImageView android:id="@+id/roundedImageView" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/image" android:background="@color/white" android:scaleType="centerCrop" /> </android.support.v7.widget.CardView>


Romain Guy es donde está.

Versión reducida de la siguiente manera.

Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap(); Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig()); Canvas canvas = new Canvas(bitmapRounded); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)); canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint); imageView.setImageBitmap(bitmapRounded);


Si bien la respuesta anterior funciona, Romain Guy (un desarrollador central de Android) muestra un mejor método en su blog que usa menos memoria al usar un sombreado que no crea una copia del mapa de bits. La esencia general de la funcionalidad está aquí:

BitmapShader shader; shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(shader); RectF rect = new RectF(0.0f, 0.0f, width, height); // rect contains the bounds of the shape // radius is the radius in pixels of the rounded corners // paint contains the shader that will texture the shape canvas.drawRoundRect(rect, radius, radius, paint);

Las ventajas de esto sobre otros métodos es que:

  • no crea una copia separada del mapa de bits, que usa mucha memoria con imágenes grandes [en comparación con la mayoría de las otras respuestas aquí]
  • Soporta el método antialisasing [vs clipPath]
  • soporta alpha [vs xfermode + porterduff method]
  • Soporta aceleración de hardware [método vs clipPath]
  • solo dibuja una vez en el lienzo [contra los métodos xfermode y clippath]

He creado un RoundedImageView basado en este código que envuelve esta lógica en un ImageView y agrega el soporte adecuado de ScaleType y un borde redondeado opcional.


¡Muchas respuestas!

Seguí este ejemplo que algunas personas también han sugerido: http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

Sin embargo, lo que necesitaba era un círculo de color, detrás de una imagen transparente. Para quien esté interesado en hacer lo mismo ...

1) Establezca FrameLayout en el ancho y la altura, en mi caso, el tamaño de la imagen (50dp).
2) Coloque el ImageView que tiene el src = "@drawable / ...", sobre el ImageView que tiene la imagen. Dale una identificación, en mi caso lo llamé iconShape
3) Drawable mask.xml debería tener un color sólido de #ffffffff 4) Si quieres cambiar dinámicamente el color del círculo en tu código, hazlo

ImageView iv2 = (ImageView) v.findViewById(R.id.iconShape); Drawable shape = getResources().getDrawable(R.drawable.mask); shape.setColorFilter(Color.BLUE, Mode.MULTIPLY); iv2.setImageDrawable(shape);


¿Por qué no hacer clipping en draw ()?

Aquí está mi solución:

  • extender RelativeLayout con recorte
  • ponga ImageView (u otras vistas) en el diseño:

código:

public class RoundRelativeLayout extends RelativeLayout { private final float radius; public RoundRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray attrArray = context.obtainStyledAttributes(attrs, R.styleable.RoundRelativeLayout); radius = attrArray.getDimension( R.styleable.RoundRelativeLayout_radius, 0); } private boolean isPathValid; private final Path path = new Path(); private Path getRoundRectPath() { if (isPathValid) { return path; } path.reset(); int width = getWidth(); int height = getHeight(); RectF bounds = new RectF(0, 0, width, height); path.addRoundRect(bounds, radius, radius, Direction.CCW); isPathValid = true; return path; } @Override protected void dispatchDraw(Canvas canvas) { canvas.clipPath(getRoundRectPath()); super.dispatchDraw(canvas); } @Override public void draw(Canvas canvas) { canvas.clipPath(getRoundRectPath()); super.draw(canvas); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int oldWidth = getMeasuredWidth(); int oldHeight = getMeasuredHeight(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); int newWidth = getMeasuredWidth(); int newHeight = getMeasuredHeight(); if (newWidth != oldWidth || newHeight != oldHeight) { isPathValid = false; } } }


A continuación se crea un objeto de diseño de rectángulo redondeado que dibuja un rectángulo redondeado alrededor de los objetos secundarios que se colocan en él. También demuestra cómo crear vistas y diseños mediante programación sin utilizar los archivos XML de diseño.

package android.example; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.ViewGroup.LayoutParams; import android.widget.LinearLayout; import android.widget.TextView; public class MessageScreen extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int mainBackgroundColor = Color.parseColor("#2E8B57"); int labelTextColor = Color.parseColor("#FF4500"); int messageBackgroundColor = Color.parseColor("#3300FF"); int messageTextColor = Color.parseColor("#FFFF00"); DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); float density = metrics.density; int minMarginSize = Math.round(density * 8); int paddingSize = minMarginSize * 2; int maxMarginSize = minMarginSize * 4; TextView label = new TextView(this); /* * The LayoutParams are instructions to the Layout that will contain the * View for laying out the View, so you need to use the LayoutParams of * the Layout that will contain the View. */ LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); label.setLayoutParams(labelLayoutParams); label.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); label.setPadding(paddingSize, paddingSize, paddingSize, paddingSize); label.setText(R.string.title); label.setTextColor(labelTextColor); TextView message = new TextView(this); RoundedRectangle.LayoutParams messageLayoutParams = new RoundedRectangle.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); /* * This is one of the calls must made to force a ViewGroup to call its * draw method instead of just calling the draw method of its children. * This tells the RoundedRectangle to put some extra space around the * View. */ messageLayoutParams.setMargins(minMarginSize, paddingSize, minMarginSize, maxMarginSize); message.setLayoutParams(messageLayoutParams); message.setTextSize(TypedValue.COMPLEX_UNIT_SP, paddingSize); message.setText(R.string.message); message.setTextColor(messageTextColor); message.setBackgroundColor(messageBackgroundColor); RoundedRectangle messageContainer = new RoundedRectangle(this); LinearLayout.LayoutParams messageContainerLayoutParams = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); messageContainerLayoutParams.setMargins(paddingSize, 0, paddingSize, 0); messageContainer.setLayoutParams(messageContainerLayoutParams); messageContainer.setOrientation(LinearLayout.VERTICAL); /* * This is one of the calls must made to force a ViewGroup to call its * draw method instead of just calling the draw method of its children. * This tells the RoundedRectangle to color the the exta space that was * put around the View as well as the View. This is exterior color of * the RoundedRectangle. */ messageContainer.setBackgroundColor(mainBackgroundColor); /* * This is one of the calls must made to force a ViewGroup to call its * draw method instead of just calling the draw method of its children. * This is the interior color of the RoundedRectangle. It must be * different than the exterior color of the RoundedRectangle or the * RoundedRectangle will not call its draw method. */ messageContainer.setInteriorColor(messageBackgroundColor); // Add the message to the RoundedRectangle. messageContainer.addView(message); // LinearLayout main = new LinearLayout(this); LinearLayout.LayoutParams mainLayoutParams = new LinearLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); main.setLayoutParams(mainLayoutParams); main.setOrientation(LinearLayout.VERTICAL); main.setBackgroundColor(mainBackgroundColor); main.addView(label); main.addView(messageContainer); setContentView(main); } }

La clase para el objeto de diseño RoundedRectangle es como se define aquí:

/** * A LinearLayout that draws a rounded rectangle around the child View that was added to it. */ package android.example; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.widget.LinearLayout; /** * A LinearLayout that has rounded corners instead of square corners. * * @author Danny Remington * * @see LinearLayout * */ public class RoundedRectangle extends LinearLayout { private int mInteriorColor; public RoundedRectangle(Context p_context) { super(p_context); } public RoundedRectangle(Context p_context, AttributeSet attributeSet) { super(p_context, attributeSet); } // Listener for the onDraw event that occurs when the Layout is drawn. protected void onDraw(Canvas canvas) { Rect rect = new Rect(0, 0, getWidth(), getHeight()); RectF rectF = new RectF(rect); DisplayMetrics metrics = new DisplayMetrics(); Activity activity = (Activity) getContext(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); float density = metrics.density; int arcSize = Math.round(density * 10); Paint paint = new Paint(); paint.setColor(mInteriorColor); canvas.drawRoundRect(rectF, arcSize, arcSize, paint); } /** * Set the background color to use inside the RoundedRectangle. * * @param Primitive int - The color inside the rounded rectangle. */ public void setInteriorColor(int interiorColor) { mInteriorColor = interiorColor; } /** * Get the background color used inside the RoundedRectangle. * * @return Primitive int - The color inside the rounded rectangle. */ public int getInteriorColor() { return mInteriorColor; } }


Kotlin

import android.graphics.BitmapFactory import android.os.Bundle import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory import kotlinx.android.synthetic.main.activity_main.* val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage) val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap) rounded.cornerRadius = 20f profileImageView.setImageDrawable(rounded)

Para hacer ImageViewcircular podemos cambiar cornerRadiuscon:

rounded.isCircular = true


Aquí hay un ejemplo simple que reemplaza a imageView, luego también puede usarlo en el diseñador de diseños para obtener una vista previa.

public class RoundedImageView extends ImageView { public RoundedImageView(Context context) { super(context); } public RoundedImageView(Context context, AttributeSet attrs) { super(context, attrs); } public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public void setImageDrawable(Drawable drawable) { float radius = 0.1f; Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap); rid.setCornerRadius(bitmap.getWidth() * radius); super.setImageDrawable(rid); }

}

Esto es para una solución rápida. El radio se usa en todas las esquinas y se basa en el porcentaje del ancho del mapa de bits.

Acabo de anular setImageDrawabley usar el método de soporte v4 para dibujar con mapa de bits redondeado.

Uso:

<com.example.widgets.RoundedImageView android:layout_width="39dp" android:layout_height="39dp" android:src="@drawable/your_drawable" />

Vista previa con imageView y imageView personalizado:


Responda a la pregunta que se redirige aquí: "¿Cómo crear un ImageView circular en Android?"

public static Bitmap getRoundBitmap(Bitmap bitmap) { int min = Math.min(bitmap.getWidth(), bitmap.getHeight()); Bitmap bitmapRounded = Bitmap.createBitmap(min, min, bitmap.getConfig()); Canvas canvas = new Canvas(bitmapRounded); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)); canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min/2, min/2, paint); return bitmapRounded; }


Si está utilizando Glide Library, esto sería útil:

Glide.with(getApplicationContext()) .load(image_url) .asBitmap() .centerCrop() .into(new BitmapImageViewTarget(imageView) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource); circularBitmapDrawable.setCornerRadius(dpToPx(10)); circularBitmapDrawable.setAntiAlias(true); imageView.setImageDrawable(circularBitmapDrawable); } }); public int dpToPx(int dp) { DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics(); return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)); }


Usa esto para obtener una imagen circular con borde

public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) { if (bitmap == null || bitmap.isRecycled()) { return null; } int borderWidth=(int)(bitmap.getWidth()/40); final int width = bitmap.getWidth() + borderWidth; final int height = bitmap.getHeight() + borderWidth; Bitmap canvasBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(shader); Canvas canvas = new Canvas(canvasBitmap); float radius = width > height ? ((float) height) / 2f : ((float) width) / 2f; canvas.drawCircle(width / 2, height / 2, radius, paint); paint.setShader(null); paint.setStyle(Paint.Style.STROKE); paint.setColor(bordercolor); paint.setStrokeWidth(borderWidth); canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2, paint); return canvasBitmap; }


Aplica una forma a tu imageViewcomo se muestra a continuación:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <solid android:color="#faf5e6" /> <stroke android:width="1dp" android:color="#808080" /> <corners android:radius="15dp" /> <padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp" /> </shape>

puede ser de ayuda para usted amigo


Con la ayuda de la biblioteca Glide y la clase RoundedBitmapDrawableFactory es fácil de lograr. Es posible que necesite crear una imagen de marcador de posición circular.

Glide.with(context) .load(imgUrl) .asBitmap() .placeholder(R.drawable.placeholder) .error(R.drawable.placeholder) .into(new BitmapImageViewTarget(imgProfilePicture) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(), Bitmap.createScaledBitmap(resource, 50, 50, false)); drawable.setCornerRadius(10); //drawable.setCircular(true); imgProfilePicture.setImageDrawable(drawable); } });


Desde hace poco, hay otra forma: usar la API generada de Glide . Requiere un poco de trabajo inicial, pero luego le da todo el poder de Glide con la flexibilidad para hacer cualquier cosa porque retuerce el código real, así que creo que es una buena solución a largo plazo. Además, el uso es muy simple y limpio.

Primero, configure Glide versión 4+:

implementation ''com.github.bumptech.glide:glide:4.6.1'' annotationProcessor ''com.github.bumptech.glide:compiler:4.6.1''

Luego cree la clase de módulo de aplicación de Glid para activar el proceso de anotación:

@GlideModule public final class MyAppGlideModule extends AppGlideModule {}

Luego crea la extensión Glide que realmente hace el trabajo. Puedes personalizarlo para hacer lo que quieras:

@GlideExtension public class MyGlideExtension { private MyGlideExtension() {} @NonNull @GlideOption public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) { int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT)); return options.transforms(new RoundedCorners(px)); } }

Después de agregar estos archivos, construye tu proyecto.

Entonces úsalo en tu código así:

GlideApp.with(this) .load(imageUrl) .roundedCorners(getApplicationContext(), 5) .into(imageView);


Estoy usando una vista personalizada que diseño sobre las otras y que solo dibuja las 4 pequeñas esquinas invertidas en el mismo color que el fondo.

Ventajas:

  • No asigna un mapa de bits.
  • Funciona cualquiera que sea la vista que quieras aplicar a las esquinas redondeadas.
  • Funciona para todos los niveles de API;)

Código:

public class RoundedCornersView extends View { private float mRadius; private int mColor = Color.WHITE; private Paint mPaint; private Path mPath; public RoundedCornersView(Context context) { super(context); init(); } public RoundedCornersView(Context context, AttributeSet attrs) { super(context, attrs); init(); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.RoundedCornersView, 0, 0); try { setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0)); setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE)); } finally { a.recycle(); } } private void init() { setColor(mColor); setRadius(mRadius); } private void setColor(int color) { mColor = color; mPaint = new Paint(); mPaint.setColor(mColor); mPaint.setStyle(Paint.Style.FILL); mPaint.setAntiAlias(true); invalidate(); } private void setRadius(float radius) { mRadius = radius; RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius); mPath = new Path(); mPath.moveTo(0,0); mPath.lineTo(0, mRadius); mPath.arcTo(r, 180, 90); mPath.lineTo(0,0); invalidate(); } @Override protected void onDraw(Canvas canvas) { /*This just draws 4 little inverted corners */ int w = getWidth(); int h = getHeight(); canvas.drawPath(mPath, mPaint); canvas.save(); canvas.translate(w, 0); canvas.rotate(90); canvas.drawPath(mPath, mPaint); canvas.restore(); canvas.save(); canvas.translate(w, h); canvas.rotate(180); canvas.drawPath(mPath, mPaint); canvas.restore(); canvas.translate(0, h); canvas.rotate(270); canvas.drawPath(mPath, mPaint); } }


Muchas gracias a la primera respuesta. Aquí está la versión modificada para convertir una imagen rectangular en una cuadrada (y redondeada) y el color de relleno se pasa como parámetro.

public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) { Bitmap inpBitmap = bitmap; int width = 0; int height = 0; width = inpBitmap.getWidth(); height = inpBitmap.getHeight(); if (width <= height) { height = width; } else { width = height; } Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, width, height); final RectF rectF = new RectF(rect); final float roundPx = pixels; paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(color); canvas.drawRoundRect(rectF, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(inpBitmap, rect, rect, paint); return output; }


Puedes probar esta biblioteca - RoundedImageView

Es:

Un rápido ImageView que admite esquinas redondeadas, óvalos y círculos. Un superconjunto completo de CircleImageView.

Lo he usado en mi proyecto, y es muy fácil.


Si su imagen está en Internet, la mejor manera es usar glide y RoundedBitmapDrawableFactory(desde API 21, pero está disponible en la biblioteca de soporte), de esta forma:

Glide.with(ctx).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) { @Override protected void setResource(Bitmap res) { RoundedBitmapDrawable bitmapDrawable = RoundedBitmapDrawableFactory.create(ctx.getResources(), res); bitmapDrawable.setCircular(true);//comment this line and uncomment the next line if you dont want it fully cricular //circularBitmapDrawable.setCornerRadius(cornerRadius); imageView.setImageDrawable(bitmapDrawable); } });


puede usar solo ImageViewen su diseño y usar glide, puede aplicar esquinas redondeadas utilizando este método.

primero en tu gradle escribe,

compile ''com.github.bumptech.glide:glide:3.7.0''

para imagen con esquinas redondeadas,

public void loadImageWithCorners(String url, ImageView view) { Glide.with(context) .load(url) .asBitmap() .centerCrop() .placeholder(R.color.gray) .error(R.color.gray) .diskCacheStrategy(DiskCacheStrategy.SOURCE) .into(new BitmapImageViewTarget(view) { @Override protected void setResource(Bitmap resource) { RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource); circularBitmapDrawable.setCornerRadius(32.0f); // radius for corners view.setImageDrawable(circularBitmapDrawable); } }); }

método de llamada:

loadImageWithCorners("your url","your imageview");