android - example - image view cardview
Hacer que ImageView se ajuste al ancho de CardView (9)
A veces, usar
Glide
lugar de
Picasso
para cargar imágenes también ayuda.
Tengo un
CardView
con esquinas redondeadas, quiero tener un
ImageView
en la parte superior como se muestra en el ejemplo tomado de las pautas de diseño de materiales a continuación.
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp">
<!-- ... -->
</android.support.v7.widget.CardView>
Luego dentro de
CardView
tengo este
ImageView
<ImageView
android:id="@+id/imageView"
android:layout_width="fill_parent"
android:layout_height="150dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"
android:src="@drawable/default_cover" />
Si tengo
card_view:cardCornerRadius
establecido en
0dp
, el
ImageView
ajusta a la tarjeta como yo quiero.
Sin embargo, las pautas de diseño de materiales establecen que las tarjetas deben tener esquinas redondeadas y no esquinas cuadradas.
El problema que tengo es cuando configuro
card_view:cardCornerRadius
en algo diferente a
0dp
, por ejemplo,
4dp
, entonces sucede lo siguiente:
Como se puede ver, el
ImageView
no cabe en el
CardView
.
Mi pregunta es, ¿cómo puedo hacer que este
ImageView
ajuste al diseño del
CardView
cuando tiene esquinas redondeadas?
EDITAR 29/09/2015
https://github.com/vinc3m1/RoundedImageView agregó soporte para redondear las esquinas seleccionadas
También puede usar makeramen RoundedImageView https://github.com/vinc3m1/RoundedImageView , y eliminar el relleno automático en CardView para el uso previo de LolliPop
yourCardView.setPreventCornerOverlap (falso);
Y luego configure el relleno que necesita para mostrar las sombras de la vista de tarjeta
Haga un
bck_rounded.xml
en una carpeta
bck_rounded.xml
.
Dale un radio que sea el mismo que el de card_view.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:radius="4dp" />
</shape>
Aplique dentro de su imageView:
android:background="@drawable/bck_rounded"
Intento usar la combinación con cardview y imageview, por lo que será así:
android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="160dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
app:cardCornerRadius="8dp"
android:elevation="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/kmp_warna1"
android:scaleType="centerCrop"/>
</android.support.v7.widget.CardView>
Solo agrego el radio de esquina y el atributo de elevación en la vista de tarjeta, y scaletype = centerCrop en la vista de imagen
Espero que ayude
Necesitas hacer 2 cosas:
1) Llame a
setPreventCornerOverlap(false)
en su CardView.
2) Poner Imageview redondeado dentro de CardView
Al redondear su vista de imagen, tuve el mismo problema, así que hice una biblioteca en la que puede establecer diferentes radios en cada esquina . Hay una buena biblioteca (RoundedImageView de vinc3m1) que admite esquinas redondeadas en ImageView, pero solo admite los mismos radios en todas las esquinas. Pero quería que se redondeara solo en las esquinas superior izquierda y superior derecha.
Finalmente obtuve el resultado que quería a continuación.
https://github.com/pungrue26/SelectableRoundedImageView
Resolví el problema con la configuración
1)
app:cardUseCompatPadding="false"
2) establecer un fondo redondeado de
imageView
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<corners android:radius="4dp" />
</shape>
Si el tamaño de su imagen (ancho) se fija con el ancho de su
ImageView
, solo tiene que cambiar su atributo
ImageView
a:
android:scaleType="fitXY"
Es decir. Sin redondeo de esquina de imagen adicional, sin trabajo ocupado. Además, es eficiente para el rendimiento de la aplicación.
Nota: mi sugerencia puede no ser apropiada para imágenes pequeñas con
ImageView
gran tamaño.
Tienes que personalizar tu ImageView.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
public class RoundedImageView extends android.support.v7.widget.AppCompatImageView {
private Paint mPaint;
private Path mPath;
private Bitmap mBitmap;
private Matrix mMatrix;
private int mRadius = convertDpToPixel(10);
private int mWidth;
private int mHeight;
private Drawable mDrawable;
public RoundedImageView(Context context) {
super(context);
init();
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPath = new Path();
}
public int convertDpToPixel(int dp) {
DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
}
@Override
public void setImageDrawable(Drawable drawable) {
mDrawable = drawable;
if (drawable == null) {
return;
}
mBitmap = drawableToBitmap(drawable);
int bDIWidth = mBitmap.getWidth();
int bDIHeight = mBitmap.getHeight();
//Fit to screen.
float scale;
if ((mHeight / (float) bDIHeight) >= (mWidth / (float) bDIWidth)) {
scale = mHeight / (float) bDIHeight;
} else {
scale = mWidth / (float) bDIWidth;
}
float borderLeft = (mWidth - (bDIWidth * scale)) / 2;
float borderTop = (mHeight - (bDIHeight * scale)) / 2;
mMatrix = getImageMatrix();
RectF drawableRect = new RectF(0, 0, bDIWidth, bDIHeight);
RectF viewRect = new RectF(borderLeft, borderTop, (bDIWidth * scale) + borderLeft, (bDIHeight * scale) + borderTop);
mMatrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
invalidate();
}
private Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = MeasureSpec.getSize(widthMeasureSpec);
mHeight = MeasureSpec.getSize(heightMeasureSpec);
if ((mDrawable != null) && (mHeight > 0) && (mWidth > 0)) {
setImageDrawable(mDrawable);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap == null) {
return;
}
canvas.drawColor(Color.TRANSPARENT);
mPath.reset();
mPath.moveTo(0, mRadius);
mPath.lineTo(0, canvas.getHeight());
mPath.lineTo(canvas.getWidth(), canvas.getHeight());
mPath.lineTo(canvas.getWidth(), mRadius);
mPath.quadTo(canvas.getWidth(), 0, canvas.getWidth() - mRadius, 0);
mPath.lineTo(mRadius, 0);
mPath.quadTo(0, 0, 0, mRadius);
canvas.drawPath(mPath, mPaint);
canvas.clipPath(mPath);
canvas.drawBitmap(mBitmap, mMatrix, mPaint);
}
}
Y en layout.xml
<com.example.widget.RoundedImageViewmageView
android:id="@+id/ivProductImg"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="fitXY"
/>
Conseguí que esto funcionara poniendo un
RoundedImageView
dentro de un
CardView
.
También debe establecer los atributos apropiados de
CardView
.
https://medium.com/@etiennelawlor/layout-tips-for-pre-and-post-lollipop-bcb2e4cdd6b2#.kmb24wtkk