web-dev-qa-db-fra.com

Faire en sorte que ImageView épouse la largeur de CardView

J'ai une CardView avec des coins arrondis, je veux avoir une ImageView en haut, comme indiqué dans l'exemple tiré des directives de conception des matériaux ci-dessous.

components_cards8.png

<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>

Puis à l'intérieur de la CardView j'ai cette 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 le card_view:cardCornerRadius est défini sur 0dp, alors la ImageView correspond à la carte, comme je le souhaite.

image_1

Toutefois, les règles de conception des matériaux déclarent que les cartes doivent avoir des coins arrondis et non des coins carrés.

Le problème que j'ai, c’est lorsque je règle le card_view:cardCornerRadius sur autre chose que 0dp, par exemple. 4dp, alors ce qui suit se produit:

image_2

Comme on peut le constater, la ImageView ne rentre pas dans la CardView.

Ma question est la suivante: comment puis-je adapter cette ImageView à la présentation de la CardView lorsque ses angles sont arrondis?.

56
Dan

Vous devez faire 2 choses:

1) Appelez setPreventCornerOverlap(false) sur votre CardView.

2) Placez arrondi ImageView dans CardView

À propos de l’arrondissement de votre imageview, j’avais le même problème et j’ai donc créé une bibliothèque sur laquelle vous pouvez définir rayons différents à chaque angle. Il existe une bonne bibliothèque (RoundedImageView de vinc3m1) qui prend en charge les angles arrondis dans ImageView, mais elle ne prend en charge que les mêmes rayons dans tous les angles. Mais je voulais que ce soit arrondi uniquement dans les coins supérieur gauche et supérieur droit.

Enfin, j'ai obtenu le résultat que je voulais comme ci-dessous.

https://github.com/pungrue26/SelectableRoundedImageView

Rounded ImageView inside CardView

53
김준호

Si votre taille d'image (largeur) est fixée à votre largeur ImageView, il vous suffit de changer l'attribut ImageView en:

Android:scaleType="fitXY"

C'est. Pas d’arrondi supplémentaire, pas de travail occupé. À côté de cela efficace pour les performances de l'application.

Remarque: ma suggestion peut ne pas convenir pour une petite image avec une grande taille ImageView.

18
james

 CardView with ImageView

J'ai réussi à mettre cela en place en mettant une RoundedImageView dans une CardView. Vous devez également définir les attributs CardView appropriés. 

https://medium.com/@etiennelawlor/layout-tips-for-pre-and-post-Lollipop-bcb2e4cdd6b2#.kmb24wtkk

15
toobsco42

EDIT 2015/09/29

https://github.com/vinc3m1/RoundedImageView ajout du support de l'arrondi des coins sélectionnés

Vous pouvez également utiliser makeramen RoundedImageView https://github.com/vinc3m1/RoundedImageView , Et supprimer le remplissage automatique dans CardView pour une utilisation préalable à Lollipop. 

yourCardView.setPreventCornerOverlap (false); 

Et définissez ensuite le rembourrage dont vous avez besoin pour afficher les ombres de cardview

6
Penzzz

Créez un bck_rounded.xml dans le dossier drawable. Donnez-lui un rayon identique à celui 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>

Appliquer à l'intérieur de votre image Voir: Android:background="@drawable/bck_rounded"

3
Mohammed Ali

J'ai résolu le problème de réglage
1) app:cardUseCompatPadding="false"
2) définition d’un imageView fond

<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <corners Android:radius="4dp" />
</shape>
1
S Ravi Kumar

Parfois, utiliser Glide au lieu de Picasso pour charger des images est également utile.

0
Bek

j'essaie d'utiliser la combinaison avec cardview et imageview, donc ce sera comme ça:

    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>

Je viens d'ajouter l'attribut rayon de rayon et élévation sur cardview, et scaletype = centerCrop sur la vue d'image

J'espère que ça va aider

0
Cevin Ways

Vous devez personnaliser votre 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);
}
}

Et dans layout.xml

<com.example.widget.RoundedImageViewmageView
            Android:id="@+id/ivProductImg"
            Android:layout_width="match_parent"
            Android:layout_height="150dp"
            Android:scaleType="fitXY"
            />
0
Vishal G. Gohel