Reputation: 1920
I have a Framelayout which has some rounded corners through a drawable xml file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- View background color -->
<solid
android:color="@color/colorPrimary" >
</solid>
<!-- The radius makes the corners rounded -->
<corners
android:topLeftRadius="20dp"
android:bottomRightRadius="20dp" >
</corners>
</shape>
Inside the FrameLayout i have 2 TextViews and an imageView which gets loaded with a bitmap programmatically. The problem is that i have tried everything to give the ImageView same rounded corners as the FrameLayout so i decided to replace the ImageView with another simple View (as FrameLayout or smth) and set the bitmap image as a background of the view. This didn't work either.
So is there any way in a view to set the drawable with the corners in the xml, and when later programmatically change the background with a bitmap to keep somehow the rounded corners with the new image loaded? Thank you
Upvotes: 1
Views: 559
Reputation: 14173
Solution
Step 1. Go to res/values
folder, create a xml file named attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundedImageView">
<attr name="topLeftCorner" format="dimension" />
<attr name="topRightCorner" format="dimension" />
<attr name="bottomRightCorner" format="dimension" />
<attr name="bottomLeftCorner" format="dimension" />
</declare-styleable>
</resources>
Step 2. Create a class that extends from AppCompatImageView, named RoundedImageView
public class RoundedImageView extends AppCompatImageView {
private final Path path = new Path();
private final float[] radii = new float[8];
private final RectF rect = new RectF();
public RoundedImageView(@NonNull Context context) {
this(context, null);
}
public RoundedImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView);
try {
int topLeftCorner = a.getDimensionPixelSize(R.styleable.RoundedImageView_topLeftCorner, 0);
int topRightCorner = a.getDimensionPixelSize(R.styleable.RoundedImageView_topRightCorner, 0);
int bottomRightCorner = a.getDimensionPixelSize(R.styleable.RoundedImageView_bottomRightCorner, 0);
int bottomLeftCorner = a.getDimensionPixelSize(R.styleable.RoundedImageView_bottomLeftCorner, 0);
radii[0] = topLeftCorner;
radii[1] = topLeftCorner;
radii[2] = topRightCorner;
radii[3] = topRightCorner;
radii[4] = bottomRightCorner;
radii[5] = bottomRightCorner;
radii[6] = bottomLeftCorner;
radii[7] = bottomLeftCorner;
} finally {
a.recycle();
}
}
@Override
protected void onDraw(Canvas canvas) {
rect.left = 0;
rect.top = 0;
rect.right = getWidth();
rect.bottom = getHeight();
path.rewind();
path.addRoundRect(rect, radii, Path.Direction.CW);
canvas.clipPath(path);
super.onDraw(canvas);
}
}
Step 3. Use it from layout file.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F00"
android:gravity="center">
<com.example.roundedimageview.RoundedImageView
android:id="@+id/imageView"
android:layout_width="240dp"
android:layout_height="240dp"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:src="@drawable/ic_android"
app:bottomRightCorner="20dp"
app:topLeftCorner="20dp" />
</FrameLayout>
Result
Benefit
You can set the corner radius for top-left, top-right, bottom-right, bottom-left.
Work with Glide, Picasso library
Limitations
Upvotes: 1
Reputation: 182
You can use libraries to achieve it easily. But there is an other way to do. You can use your image within CardView. When you set cardCornerRadius feature the image corners which overlaying the cardview's corners will be rounded too.
Or try this
ImageView yourImageView = findViewById(R.id.yourImageView);
Bitmap bitmap =((BitmapDrawable) ResourcesCompat.getDrawable(R.drawable.anyPicture)).getBitmap();
Bitmap roundedImageBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas=new Canvas(roundedImageBitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight())), 100, 100, paint); // You can adjust the roundness here
yourimageView.setImageBitmap(roundedImageBitmap);
Upvotes: 0