2014-12-10 9 views
48

Ho uno CardView con gli angoli arrotondati, voglio avere uno ImageView nella parte superiore come mostrato nell'esempio tratto dalle linee guida sulla progettazione dei materiali di seguito.Realizza ImageView adatta larghezza di CardView

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> 

Poi all'interno del CardView ho questo 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" /> 

Se ho il set card_view:cardCornerRadius al 0dp poi il ImageView adatta la carta come come lo voglio a.

image_1

Tuttavia, lo stato material design guidelines che le carte dovrebbe avere spigoli arrotondati e gli angoli non quadrati.

Il problema che ho è quando ho impostato il card_view:cardCornerRadius su un valore diverso da 0dp, ad es. 4dp, allora avviene quanto segue:

image_2

Come si vede, il ImageView non rientra nel CardView.

La mia domanda è, come posso rendere questo ImageView adattato al layout dello CardView quando ha gli angoli arrotondati.

+0

Daniel potrebbe essere accadendo su API inferiore a 21 (5.0) Lollipop, lo stesso problema esiste in gioco App Store così –

+0

@Vipinhelloindia Sì hai ragione, questo succede solo pre-L. La panoramica della classe per CardView (https://developer.android.com/reference/android/support/v7/widget/CardView.html) descrive cosa succede prima di L perché il ritaglio di un angolo sembra essere una caratteristica di L e solo sopra. – Dan

risposta

40

Hai bisogno di fare 2 cose:

1) Chiamare setPreventCornerOverlap(false) sul tuo CardView.

2) Mettere arrotondato IMAGEVIEW all'interno CardView

Chi arrotondamento tua imageview, ho avuto lo stesso problema così ho fatto una libreria che è possibile impostare raggi diversi su ogni angoli. C'è una buona libreria (RoundedImageView di vinc3m1) che supporta gli angoli arrotondati su ImageView, ma supporta solo gli stessi raggi su ogni angolo. Ma volevo che fosse arrotondato solo in alto a sinistra e in alto a destra.

Finalmente ho ottenuto il risultato che volevo come sotto.

https://github.com/pungrue26/SelectableRoundedImageView

Rounded ImageView inside CardView

+2

setPreventCornerOverlap (false) per pre lolipop aiuta davvero – Penzzz

+0

Nelle versioni più recenti, Round3ImageView di vinc3m1 supporta l'arrotondamento degli angoli specifici. –

3

Creare un bck_rounded.xml nella cartella drawable. Dagli un raggio uguale a card_view.

<?xml version="1.0" encoding="utf-8"?> 
    <shape xmlns:android="http://schemas.android.com/apk/res/android" > 
     <corners android:radius="4dp" /> 
    </shape> 

applicare al vostro imageView-android:background="@drawable/bck_rounded.xml"

+0

la vista immagine dovrebbe avere angoli arrotondati ... prova questo: http://stackoverflow.com/q/20743859/3879470 con tratto e riempimento. –

+0

@DanielB ha aggiunto il tratto e il riempimento? –

5

EDIT 2015/09/29

https://github.com/vinc3m1/RoundedImageView aggiunto il supporto di arrotondamento degli angoli selezionati

È inoltre possibile utilizzare makeramen RoundedImageView https://github.com/vinc3m1/RoundedImageView, e per rimuovere il riempimento automatico in CardView per pre LolliPop utilizzare

yourCardView.setPreventCornerOverlap (false);

E quindi impostare imbottitura si needded per mostrare le ombre di CardView

+1

RoundedImageView di vinc3m1 è una buona libreria, ma supporta solo gli stessi raggi su ogni angolo. Ma ImageView all'interno di CardView deve essere arrotondato solo in alto a sinistra e in alto a destra. Così ne ho fatto uno che è possibile impostare diversi raggi su ogni angolo. https://github.com/pungrue26/SelectableRoundedImageView –

+0

Hai ragione.Proverò la tua libà un giorno. L'ultima volta che ho affrontato un problema simile ho nascosto gli angoli inferiori da un'altra vista, ad esempio la visualizzazione del testo. Tuttavia, una soluzione sporca. – Penzzz

14

CardView with ImageView

ho avuto questo lavoro mettendo un RoundedImageView all'interno di una CardView. Inoltre è necessario impostare gli attributi CardView appropriati.

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

+1

Questo è stato davvero utile, grazie. – Ishaan

+8

Si prega di aggiungere informazioni rilevanti per rispondere invece di fare affidamento sul collegamento. 'RoundedImageView' non è una classe ufficiale. – AnthonyW

10

Se il formato dell'immagine (larghezza) è fissato con la larghezza delle ImageView, basta solo fare è cambiare l'attributo ImageView a:

android:scaleType="fitXY" 

che è. Nessun arrotondamento degli angoli dell'immagine aggiuntivo, nessun lavoro intenso. Accanto è efficiente per le prestazioni dell'app.

Nota: il mio suggerimento potrebbe non essere appropriato per immagini di piccole dimensioni con dimensioni grandi ImageView.

+0

Bordi perfetti e lisci, il miglior modo per aggirare! –

+0

Molto elegante e al punto soluzione –

+0

non ha funzionato per me – Chisko

0

ho risolto il problema con l'impostazione
1) app:cardUseCompatPadding="false"
2) l'impostazione di un arrotondato imageView sfondo

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

Devi personalizzare il tuo 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); 
} 
} 

E in layout.xml

<com.example.widget.RoundedImageViewmageView 
      android:id="@+id/ivProductImg" 
      android:layout_width="match_parent" 
      android:layout_height="150dp" 
      android:scaleType="fitXY" 
      /> 
Problemi correlati