我想让任何图像从我的ImageView是圆形的边界。
我搜索了一下,但没有找到任何有用的信息(我尝试的任何方法都不管用)。
如何通过XML实现这一点: 创建一个ImageView与某些src,并使它与边界圆形?
我想让任何图像从我的ImageView是圆形的边界。
我搜索了一下,但没有找到任何有用的信息(我尝试的任何方法都不管用)。
如何通过XML实现这一点: 创建一个ImageView与某些src,并使它与边界圆形?
当前回答
把这个答案贴出来供将来参考。你可以在com.google.android.material:material中使用ShapeableImageView。
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/img_launcher_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_margin="5dp"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:elevation="5dp"
android:maxWidth="50dp"
android:maxHeight="50dp"
android:scaleType="fitXY"
android:src="@mipmap/ic_launcher"
app:shapeAppearance="?attr/actionButtonStyle"
app:shapeAppearanceOverlay="@style/imageViewRounded"
app:strokeColor="@android:color/white" />
在你的styles.xml中添加imageviewraded样式
<style name="imageViewRounded">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">51%</item>
</style>
如果没有添加,可以添加材料设计依赖项。
implementation 'com.google.android.material:material:1.4.0'
设计是这样的
其他回答
使用材质组件库只需使用ShapeableImageView。 Somethig:
<com.google.android.material.imageview.ShapeableImageView
app:shapeAppearanceOverlay="@style/roundedImageViewRounded"
app:strokeColor="@color/....."
app:strokeWidth="1dp"
...
/>
:
<style name="roundedImageViewRounded">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
注意:它至少需要1.2.0版本。
使用jetpack合成,你可以使用CircleShape应用剪辑修饰器:
Image(
painter = painterResource(R.drawable.xxxx),
contentDescription = "xxxx",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(100.dp)
.clip(CircleShape)
.border(2.dp, Color.Blue, CircleShape)
)
2021年更新:使用Glide v4 CircleCrop参见https://bumptech.github.io/glide/doc/generatedapi.html
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
XML
<ImageView
android:id="@+id/vinyl"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="ContentDescription" />
在代码中
Glide.with(this)
.load("https://images.pexels.com/photos/3828241/pexels-photo-3828241.jpeg")
.transform(CircleCrop())
.into(rootView.findViewById<ImageView>(R.id.vinyl))
你可以简单地使用AndroidX ImageFilterView。
<androidx.constraintlayout.utils.widget.ImageFilterView
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginBottom="@dimen/margin_medium"
android:background="@color/white"
android:padding="@dimen/margin_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:roundPercent="1"
app:srcCompat="@drawable/ic_gallery" />
这个类是自定义圆形Imageview,有阴影,描边,饱和度,使用这个自定义圆形Imageview,你可以让你的图像在半径的圆形形状。圆形阴影ImageView不需要Github这个类就足够了。
添加CircularImageView到你的布局
CircularImageView c=new CircularImageView(this,screen width,screen height,Bitmap myimage);
yourLayout.addView(c);**
public class CircularImageView extends android.support.v7.widget.AppCompatImageView
{
private final Context context;
private final int width, height;
private final Paint paint;
private final Paint paintBorder,imagePaint;
private final Bitmap bitmap2;
private final Paint paint3;
private Bitmap bitmap;
private BitmapShader shader;
private float radius = 4.0f;
float x = 0.0f;
float y = 8.0f;
private float stroke;
private float strokeWidth = 0.0f;
private Bitmap bitmap3;
private int corner_radius=50;
public CircularImageView(Context context, int width, int height, Bitmap bitmap) {
super(context);
this.context = context;
this.width = width;
this.height = height;
//here "bitmap" is the square shape(width* width) scaled bitmap ..
this.bitmap = bitmap;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
paint3=new Paint();
paint3.setStyle(Paint.Style.STROKE);
paint3.setColor(Color.WHITE);
paint3.setAntiAlias(true);
paintBorder = new Paint();
imagePaint= new Paint();
paintBorder.setColor(Color.WHITE);
paintBorder.setAntiAlias(true);
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
this.bitmap2 = Bitmap.createScaledBitmap(bitmap, (bitmap.getWidth() - 40), (bitmap.getHeight() - 40), true);
imagePaint.setAntiAlias(true);
invalidate();
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Shader b;
if (bitmap3 != null)
b = new BitmapShader(bitmap3, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
else
b = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
imagePaint.setShader(b);
canvas.drawBitmap(maskedBitmap(), 20, 20, null);
}
private Bitmap maskedBitmap()
{
Bitmap l1 = Bitmap.createBitmap(width,width, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(l1);
paintBorder.setShadowLayer(radius, x, y, Color.parseColor("#454645"));
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
final RectF rect = new RectF();
rect.set(20, 20, bitmap2.getWidth(), bitmap2.getHeight());
canvas.drawRoundRect(rect, corner_radius, corner_radius, paintBorder);
canvas.drawRoundRect(rect, corner_radius, corner_radius, imagePaint);
if (strokeWidth!=0.0f)
{
paint3.setStrokeWidth(strokeWidth);
canvas.drawRoundRect(rect, corner_radius, corner_radius, paint3);
}
paint.setXfermode(null);
return l1;
}
// use seekbar here, here you have to pass "0 -- 250" here corner radius will change
public void setCornerRadius(int corner_radius)
{
this.corner_radius = corner_radius;
invalidate();
}
-------->use seekbar here, here you have to pass "0 -- 10.0f" here shadow radius will change
public void setShadow(float radius)
{
this.radius = radius;
invalidate();
}
// use seekbar here, here you have to pass "0 -- 10.0f" here stroke size will change
public void setStroke(float stroke)
{
this.strokeWidth = stroke;
invalidate();
}
private Bitmap updateSat(Bitmap src, float settingSat)
{
int w = src.getWidth();
int h = src.getHeight();
Bitmap bitmapResult =
Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvasResult = new Canvas(bitmapResult);
Paint paint = new Paint();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(settingSat);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(filter);
canvasResult.drawBitmap(src, 0, 0, paint);
return bitmapResult;
}
// use seekbar here, here you have to pass "0 -- 2.0f" here saturation will change
public void setSaturation(float sat)
{
System.out.println("qqqqqqqqqq "+sat);
bitmap3=updateSat(bitmap2, sat);
invalidate();
}
}
// Seekbar to change radius
radius_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
text_radius.setText(""+progress);
circularImageView.setCornerRadius(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Seekbar to change shadow
shadow_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
float f= 4+progress/10.0f;
text_shadow.setText(""+progress);
circularImageView.setShadow(f);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Seekbar to change saturation
saturation_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
int progressSat = saturation_seekbar.getProgress();
float sat = (float) ((progressSat*4 / 100.0f)-1.0f);
circularImageView.setSaturation(sat);
text_saturation.setText(""+progressSat);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// Seekbar to change stroke
stroke_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
if (progress==0)
{
float f=(progress*10.0f/100.0f);
circularImageView.setStroke(f);
}
else
{
float f=(progress*10.0f/100.0f);
circularImageView.setStroke(f);
}
text_stroke.setText(""+progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
//radius seekbar in xml file
<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="50"
android:max="250"
android:id="@+id/radius_seekbar"
android:layout_height="wrap_content" />
//saturation seekbar in xml file
<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="50"
android:max="100"
android:id="@+id/saturation_seekbar"
android:layout_height="wrap_content" />
//shadow seekbar in xml file
<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="0"
android:max="100"
android:id="@+id/shadow_seekbar"
android:layout_height="wrap_content" />
//stroke seekbar in xml file
<SeekBar
android:layout_width="match_parent"
android:layout_gravity="center"
android:progress="0"
android:max="100"
android:id="@+id/stroke _seekbar"
android:layout_height="wrap_content" />
另一个想法是使用ImageView的clipToOutline属性。
这是一个布局示例:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Simple view to draw borders for an image,
borders will be rounded because of the oval-shaped background. -->
<View
android:id="@+id/v_border"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/shape_border"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- Image itself: fits the border view,
a margin serves as a border width;
the key point here - is a background shape which will clip the view to its forms. -->
<ImageView
android:id="@+id/iv_image"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="4dp"
android:background="@drawable/shape_oval"
android:src="@mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="@+id/v_border"
app:layout_constraintEnd_toEndOf="@+id/v_border"
app:layout_constraintStart_toStartOf="@+id/v_border"
app:layout_constraintTop_toTopOf="@+id/v_border" />
</androidx.constraintlayout.widget.ConstraintLayout>
这是我们的shape_border可绘制对象:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="#FF00FF" />
</shape>
和shape_oval drawable:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" />
你在代码中唯一要做的就是启用clipToOutline属性:
binding.ivImage.clipToOutline = true
当然,您甚至可以使用一些BindingAdapter来避免这一行代码。