ImageView en forma circular a través de xml
Me gustaría hacer que cualquier imagen de mi ImageView
sea circular con un borde.
Busqué pero no pude encontrar ninguna información útil (cualquier cosa que intenté no funcionó).
- ¿Cómo activar el botón "Compartir" en la aplicación Android?
- ¿Atajos estáticos del androide para los sabores múltiples?
- Java.lang.NullPointerException: Intenta invocar el método virtual 'ActionBar.setNavigationMode (int)' en una referencia de objeto nulo
- Cómo configurar la pantalla completa de XML en Android
- Nombre de paquete alias o apodo
¿Cómo puedo lograr esto a través de xml: Crear un ImageView
con cierto src y hacerlo circular con un borde?
- AutoCompleteTextView con lista personalizada: cómo configurar OnItemClickListener
- Almacenar datos estáticos en Android - recurso personalizado?
- Agregar varias vistas personalizadas al diseño mediante programación
- Configuración de alfa en un BitmapDrawable en XML
- OpenCV para Android: Error al cargar el error del clasificador en cascada
- Almacenamiento de datos en línea ANDROID
- Parser SAX vs analizador XMLPull
- Error de paquete de aplicación firmada de exportación de Android
Puede hacer un círculo simple con borde blanco y contenido transparente con forma.
// res/drawable/circle.xml <shape xmlns:android="http://schemas.android.com/apk/res/android" android:innerRadius="0dp" android:shape="ring" android:thicknessRatio="1.9" android:useLevel="false" > <solid android:color="@android:color/transparent" /> <stroke android:width="10dp" android:color="@android:color/white" /> </shape>
A continuación, haga una lista de capas dibujable y ponerlo como fondo a su imagen.
// res/drawable/img.xml <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/ic_launcher"/> <item android:drawable="@drawable/circle"/> </layer-list>
Y ponerlo como fondo a su viewview.
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/img"/>
Tendrás algo así.
Este es el
Forma más simple
Que he diseñado. Prueba esto.
dependencies: compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:design:23.1.1' compile 'com.android.support:cardview-v7:23.1.1' <android.support.v7.widget.CardView android:layout_width="80dp" android:layout_height="80dp" android:elevation="12dp" android:id="@+id/view2" app:cardCornerRadius="40dp" android:layout_centerHorizontal="true" android:innerRadius="0dp" android:shape="ring" android:thicknessRatio="1.9"> <ImageView android:layout_height="80dp" android:layout_width="match_parent" android:id="@+id/imageView1" android:src="@drawable/YOUR_IMAGE" android:layout_alignParentTop="true" android:layout_centerHorizontal="true"> </ImageView> </android.support.v7.widget.CardView>
Espero que esto pueda serle de ayuda.
<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/profile_image" android:layout_width="120dp" android:layout_height="120dp" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:src="@drawable/your_picture" app:border_color="@color/white" app:border_width="3dp" />
Nota: Agregue esto en sus dependencias de build.gradle.
'compile 'de.hdodenhof:circleimageview:1.3.0'
Para ver la descripción completa: La Fuente aquí.
Los métodos anteriores no parecen funcionar si está utilizando el atributo src . Lo que hice es poner dos vistas de imagen dentro de un diseño de marco uno encima de otro como este.
<FrameLayout android:id="@+id/frame" android:layout_width="40dp" android:layout_height="40dp"> <ImageView android:id="@+id/pic" android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/my_picture" /> <ImageView android:id="@+id/circle_crop" android:layout_width="40dp" android:layout_height="40dp" android:src="@drawable/circle_crop" /> </FrameLayout>
Simplemente ponga una circular_crop.png en su carpeta dibujable que está en la forma de sus dimensiones de la imagen (cuadrado en mi caso) con el fondo blanco y un círculo transparente en el centro. Puede utilizar esta imagen si desea una imagen cuadrada.
Sólo tienes que descargar la imagen de arriba.
La siguiente es una de las formas más sencillas de hacerlo, utilice el código siguiente:
Dependencias
dependencies { ... compile 'de.hdodenhof:circleimageview:2.1.0' }
Código XML
<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/profile_image" android:layout_width="96dp" android:layout_height="96dp" android:src="@drawable/profile" app:civ_border_width="2dp" app:civ_border_color="#FF000000"/>
Captura de pantalla:
Fuente: Circular ImageView GitHub Repository
Crear la clase siguiente en su paquete
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.support.annotation.ColorInt; import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; import android.util.AttributeSet; import android.widget.ImageView; import com.synergyifs.fitnessmantra.R; /** * Created by Admin34 on 08-12-2015. */ public class CircleImageView extends ImageView { private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP; private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888; private static final int COLORDRAWABLE_DIMENSION = 2; private static final int DEFAULT_BORDER_WIDTH = 0; private static final int DEFAULT_BORDER_COLOR = Color.BLACK; private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT; private static final boolean DEFAULT_BORDER_OVERLAY = false; private final RectF mDrawableRect = new RectF(); private final RectF mBorderRect = new RectF(); private final Matrix mShaderMatrix = new Matrix(); private final Paint mBitmapPaint = new Paint(); private final Paint mBorderPaint = new Paint(); private final Paint mFillPaint = new Paint(); private int mBorderColor = DEFAULT_BORDER_COLOR; private int mBorderWidth = DEFAULT_BORDER_WIDTH; private int mFillColor = DEFAULT_FILL_COLOR; private Bitmap mBitmap; private BitmapShader mBitmapShader; private int mBitmapWidth; private int mBitmapHeight; private float mDrawableRadius; private float mBorderRadius; private ColorFilter mColorFilter; private boolean mReady; private boolean mSetupPending; private boolean mBorderOverlay; public CircleImageView(Context context) { super(context); init(); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0); mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH); mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR); mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY); mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR); a.recycle(); init(); } private void init() { super.setScaleType(SCALE_TYPE); mReady = true; if (mSetupPending) { setup(); mSetupPending = false; } } @Override public ScaleType getScaleType() { return SCALE_TYPE; } @Override public void setScaleType(ScaleType scaleType) { if (scaleType != SCALE_TYPE) { throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType)); } } @Override public void setAdjustViewBounds(boolean adjustViewBounds) { if (adjustViewBounds) { throw new IllegalArgumentException("adjustViewBounds not supported."); } } @Override protected void onDraw(Canvas canvas) { if (mBitmap == null) { return; } if (mFillColor != Color.TRANSPARENT) { canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mFillPaint); } canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mBitmapPaint); if (mBorderWidth != 0) { canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mBorderRadius, mBorderPaint); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); setup(); } public int getBorderColor() { return mBorderColor; } public void setBorderColor(@ColorInt int borderColor) { if (borderColor == mBorderColor) { return; } mBorderColor = borderColor; mBorderPaint.setColor(mBorderColor); invalidate(); } public void setBorderColorResource(@ColorRes int borderColorRes) { setBorderColor(getContext().getResources().getColor(borderColorRes)); } public int getFillColor() { return mFillColor; } public void setFillColor(@ColorInt int fillColor) { if (fillColor == mFillColor) { return; } mFillColor = fillColor; mFillPaint.setColor(fillColor); invalidate(); } public void setFillColorResource(@ColorRes int fillColorRes) { setFillColor(getContext().getResources().getColor(fillColorRes)); } public int getBorderWidth() { return mBorderWidth; } public void setBorderWidth(int borderWidth) { if (borderWidth == mBorderWidth) { return; } mBorderWidth = borderWidth; setup(); } public boolean isBorderOverlay() { return mBorderOverlay; } public void setBorderOverlay(boolean borderOverlay) { if (borderOverlay == mBorderOverlay) { return; } mBorderOverlay = borderOverlay; setup(); } @Override public void setImageBitmap(Bitmap bm) { super.setImageBitmap(bm); mBitmap = bm; setup(); } @Override public void setImageDrawable(Drawable drawable) { super.setImageDrawable(drawable); mBitmap = getBitmapFromDrawable(drawable); setup(); } @Override public void setImageResource(@DrawableRes int resId) { super.setImageResource(resId); mBitmap = getBitmapFromDrawable(getDrawable()); setup(); } @Override public void setImageURI(Uri uri) { super.setImageURI(uri); mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null; setup(); } @Override public void setColorFilter(ColorFilter cf) { if (cf == mColorFilter) { return; } mColorFilter = cf; mBitmapPaint.setColorFilter(mColorFilter); invalidate(); } private Bitmap getBitmapFromDrawable(Drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (Exception e) { e.printStackTrace(); return null; } } private void setup() { if (!mReady) { mSetupPending = true; return; } if (getWidth() == 0 && getHeight() == 0) { return; } if (mBitmap == null) { invalidate(); return; } mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mBitmapPaint.setAntiAlias(true); mBitmapPaint.setShader(mBitmapShader); mBorderPaint.setStyle(Paint.Style.STROKE); mBorderPaint.setAntiAlias(true); mBorderPaint.setColor(mBorderColor); mBorderPaint.setStrokeWidth(mBorderWidth); mFillPaint.setStyle(Paint.Style.FILL); mFillPaint.setAntiAlias(true); mFillPaint.setColor(mFillColor); mBitmapHeight = mBitmap.getHeight(); mBitmapWidth = mBitmap.getWidth(); mBorderRect.set(0, 0, getWidth(), getHeight()); mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f); mDrawableRect.set(mBorderRect); if (!mBorderOverlay) { mDrawableRect.inset(mBorderWidth, mBorderWidth); } mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f); updateShaderMatrix(); invalidate(); } private void updateShaderMatrix() { float scale; float dx = 0; float dy = 0; mShaderMatrix.set(null); if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) { scale = mDrawableRect.height() / (float) mBitmapHeight; dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f; } else { scale = mDrawableRect.width() / (float) mBitmapWidth; dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f; } mShaderMatrix.setScale(scale, scale); mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top); mBitmapShader.setLocalMatrix(mShaderMatrix); } }
Ahora utilice esta clase en el archivo xml de diseño como se muestra a continuación
<yourpackagename.CircleImageView android:id="@+id/iv_profile_pic" android:layout_width="120dp" android:layout_height="120dp" android:layout_centerHorizontal="true" app:civ_border_color="#f46d7e" app:civ_border_width="5dp"/>
Con la ayuda de la biblioteca de deslizamiento y la clase RoundedBitmapDrawableFactory es fácil de lograr. Es posible que deba 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.setCircular(true); imgProfilePicture.setImageDrawable(drawable); } });
Utilizo la forma = "oval" en vez del "anillo" abajo. Esto ha funcionado para mí. Para mantener la imagen dentro de los límites, utilizo <padding>
y establezco <adjustViewBounds>
en true en mi <ImageView>
. He intentado con imágenes de tamaño entre 50 x 50 px hasta 200×200 px.
Esto hará el truco:
Rectangle.xml
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@android:color/transparent" /> <padding android:bottom="-14dp" android:left="-14dp" android:right="-14dp" android:top="-14dp" /> </shape>
Circle.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:innerRadius="0dp" android:shape="oval" android:useLevel="false" > <solid android:color="@android:color/transparent" /> <stroke android:width="15dp" android:color="@color/verification_contact_background" /> </shape>
Profile_image.xml (La lista de capas)
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/rectangle" /> <item android:drawable="@drawable/circle"/> </layer-list>
Su diseño
<ImageView android:id="@+id/profile_image" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/default_org" android:src="@drawable/profile_image"/>
Fresco SimpleDraweeView ayudará para esto.
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/profile_view" android:layout_width="50dp" android:layout_height="50dp" fresco:placeholderImage="@drawable/YOUR_DRAWABLE" fresco:roundAsCircle="true" />
La biblioteca más simple y más lisa que encontré. Espero que esto ayude.
Biblioteca de Fresco
- Android: LocationManager vs Servicios de Google Play
- Mostrar CollapsingToolbarLayout Título SÓLO cuando se derrumbó