Make ImageView fit width of CardView

前端 未结 10 671
太阳男子
太阳男子 2020-12-04 11:00

I have a CardView with rounded corners, I want to have an ImageView at the top like shown in the example taken from the material design guidelines

相关标签:
10条回答
  • 2020-12-04 11:33

    You need to do 2 things :

    1) Call setPreventCornerOverlap(false) on your CardView.

    2) Put rounded Imageview inside CardView

    About rounding your imageview, I had the same problem so I made a library that you can set different radii on each corners. There is one good library(vinc3m1’s RoundedImageView) that supports rounded corners on ImageView, but it only supports the same radii on every corners. But I wanted it to be rounded only top left and top right corners.

    Finally I got the result what I wanted like below.

    https://github.com/pungrue26/SelectableRoundedImageView

    Rounded ImageView inside CardView

    0 讨论(0)
  • 2020-12-04 11:35

    If your image size (width) is fixed with your ImageView width, you just only have to do is change your ImageView attribute to :

    android:scaleType="fitXY"
    

    That is. No additional image corner rounding, no busy work. Beside it efficient for app's performance.

    Note : my suggestion may not appropriate for small image with large size ImageView.

    0 讨论(0)
  • 2020-12-04 11:36

    Sometimes using Glide instead of Picasso for loading images also helps.

    0 讨论(0)
  • 2020-12-04 11:39

    EDIT 2015/09/29

    https://github.com/vinc3m1/RoundedImageView added support of rounding of selected corners

    You can also use makeramen RoundedImageView https://github.com/vinc3m1/RoundedImageView, and to remove auto padding in CardView for pre LolliPop use

    yourCardView.setPreventCornerOverlap(false);

    And then set padding you needded to show shadows of cardview

    0 讨论(0)
  • 2020-12-04 11:44

    I tried using the MaskedCardView and worked for me

        class MaskedCardView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = R.attr.materialCardViewStyle
    ) : MaterialCardView(context, attrs, defStyle) {
        @SuppressLint("RestrictedApi")
        private val pathProvider = ShapeAppearancePathProvider()
        private val path: Path = Path()
        private val shapeAppearance: ShapeAppearanceModel = ShapeAppearanceModel.builder(
            context,
            attrs,
            defStyle,
            R.style.Widget_MaterialComponents_CardView
        ).build()
    
        private val rectF = RectF(0f, 0f, 0f, 0f)
    
        override fun onDraw(canvas: Canvas) {
            canvas.clipPath(path)
            super.onDraw(canvas)
        }
    
        @SuppressLint("RestrictedApi")
        override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
            rectF.right = w.toFloat()
            rectF.bottom = h.toFloat()
            pathProvider.calculatePath(shapeAppearance, 1f, rectF, path)
            super.onSizeChanged(w, h, oldw, oldh)
        }
    }
    

    And use with it the attribute app:cardPreventCornerOverlap="false"

    0 讨论(0)
  • 2020-12-04 11:46

    You have to Customize Your 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);
    }
    }
    

    And in layout.xml

    <com.example.widget.RoundedImageViewmageView
                android:id="@+id/ivProductImg"
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:scaleType="fitXY"
                />
    
    0 讨论(0)
提交回复
热议问题