使 ImageView 适合 CardView 的宽度

我有一个圆角的 CardView,我想有一个 ImageView在顶部如下面的材料设计指南的例子所示。

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>

然后在 CardView里面我有这个 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" />

如果我把 card_view:cardCornerRadius设置为 0dp,那么 ImageView就像我希望的那样适合卡片。

image_1

然而,材料设计指引规定卡片应该有圆角,而不是方角。

我遇到的问题是,当我将 card_view:cardCornerRadius设置为 0dp以外的某个值时,例如 4dp,就会发生以下情况:

image_2

可以看出,ImageView不适合 CardView

我的问题是,我怎样才能使这个 ImageView适合的布局的 CardView时,它有圆角。

92246 次浏览

drawable文件夹中创建一个 bck_rounded.xml,给它一个与 card _ view 相同的半径。

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

适用于您的图像内部视图: android:background="@drawable/bck_rounded"

编辑2015/09/29

Https://github.com/vinc3m1/roundedimageview 增加了对选定角落四舍五入的支持

您还可以使用 makeramen RoundedImageView https://github.com/vinc3m1/RoundedImageView, 并删除自动填充在 CardView 前棒棒糖使用

SetPreventCornerOverlap (false) ;

然后设置你需要显示阴影的填充物

你需要做两件事:

1)在 CardView 上拨打 setPreventCornerOverlap(false)

2)在 CardView 内置 < em > 四舍五入 Imageview

关于舍入你的图像视图,我有同样的问题,所以我做了一个库,你可以设置 每个角落有不同的半径。有一个很好的库(vinc3m1的 RoundedImageView)支持 ImageView 上的圆角,但它只支持每个圆角的相同半径。但我希望它是圆形 只有左上角和右上角。

最后我得到了我想要的结果。

Https://github.com/pungrue26/selectableroundedimageview

Rounded ImageView inside CardView

CardView with ImageView

我把一个 RoundedImageView放进一个 CardView里面,这样就可以工作了。还需要设置适当的 CardView属性。

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

如果你的图像尺寸(宽度)与你的 ImageView宽度是固定的,你只需要把你的 ImageView属性改为:

android:scaleType="fitXY"

也就是说,没有额外的图像角落舍入,没有繁忙的工作。除此之外,它的效率应用程序的性能。

注意: 我的建议可能不适合大尺寸 ImageView的小图像。

我解决了设置的问题
1) app:cardUseCompatPadding="false"
2)设置圆形 imageView背景

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

您必须自定义您的 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);
}
}

在 layout.xml 中

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

有时使用 Glide而不是 Picasso加载图像也会有所帮助。

我尝试使用组合与 cardview 和 image view,所以它会像这样:

    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>

我只是在 cardview 中添加了拐角半径和立面属性,在图像视图中添加了 scaletype = centerCrop

希望能有所帮助

我尝试使用面具卡视图,并为我工作

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

然后使用属性 app: card PreventCornerOverlap = “ false”

一个适合我的最新解决方案:

转到 AndroidManifest.xml文件并找到 manifest文件中提到的父 activity。只需在 activity 标记中添加以下一行。 android:hardwareAccelerated="true" 只要再次运行应用程序,并看到它已经解决了角半径问题。

例如:


<activity
android:name=".mvvm.activities.ABCDActivity"
android:exported="true"
android:hardwareAccelerated="true"
android:configChanges="keyboardHidden|orientation|screenSize">


<nav-graph android:value="@navigation/app_navigation"/>


</activity>

把这条线加到你的 CardView

app:cardPreventCornerOverlap="false"

ImageScale调到 ImageView

android:scaleType="fitXY"

你可以使用这些代码将一个图像放入圆形卡片视图中:

XML:

    <androidx.cardview.widget.CardView
android:layout_width="70dp"
android:layout_height="70dp"
app:cardCornerRadius="35dp"
android:shape="ring"
android:thicknessRatio="1.9"
app:cardPreventCornerOverlap="false">


<ImageView
android:id="@+id/imageView_id"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:scaleType="center"></ImageView>
</androidx.cardview.widget.CardView>

注意: cardCornerRadius 属性通常等于 CardView 的1/2宽度和高度

使用毕加索在线载入图片:

    ImageView imv = findViewById(R.id.imageView_id);
Picasso.get().load("link image").resize(300, 300).centerCrop().into(imv);