#android #imageview #android-drawable #android-bitmap #android-framelayout
#Android #imageview #android-drawable #android-растровое изображение #android-framelayout
Вопрос:
У меня есть Framelayout, у которого есть несколько закругленных углов в XML-файле, который можно рисовать
<?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>
Внутри FrameLayout у меня есть 2 TextViews и ImageView, которые программно загружаются с растровым изображением. Проблема в том, что я перепробовал все, чтобы придать ImageView те же закругленные углы, что и FrameLayout, поэтому я решил заменить ImageView другим простым представлением (как FrameLayout или что-то в этом роде) и установить растровое изображение в качестве фона представления. Это тоже не сработало.
Итак, есть ли какой-либо способ в представлении установить возможность рисования с помощью углов в xml, а позже программно изменить фон с помощью растрового изображения, чтобы каким-то образом сохранить закругленные углы при загрузке нового изображения? Спасибо
Ответ №1:
Решение
Шаг 1. Перейдите в res/values
папку, создайте XML-файл с именем 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>
Шаг 2. Создайте класс, который расширяется из AppCompatImageView, с именем 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);
}
}
Шаг 3. Используйте его из файла макета.
<?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>
Результат
Выгода
- Вы можете установить радиус угла для верхнего левого, верхнего правого, нижнего правого, нижнего левого.
- Работа с библиотекой Glide, Picasso
Ограничения
Комментарии:
1. Это очень хорошее решение. Но есть ли способ избежать Java и сделать это только с помощью xml?? Я имею в виду… whatsapp и другие делают это, расширяя Imageview?
2. @james04 Я не думаю, что стандартный Android ImageView поддерживает эту функцию, поэтому в Github есть много библиотек, где разработчики должны расширять ImageView, чтобы настраивать их внешний вид и поведение.
3. Не могли бы вы помочь мне сделать то же самое в видеообзоре? Спасибо!!
4. @james04 В Stackoverflow один вопрос относится к одной проблеме, поэтому я думаю, вы можете создать новый вопрос о VideoView, потому что ответ может отличаться при использовании VideoView. Кстати, рад вам помочь.
Ответ №2:
Вы можете использовать библиотеки для достижения этой цели легко. Но есть и другой способ сделать. Вы можете использовать свое изображение в CardView. Когда вы устанавливаете функцию cardCornerRadius, углы изображения, которые накладываются на углы cardview, также будут закруглены.
Или попробуйте это
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);
Комментарии:
1. Проблема в том, что я не хочу, чтобы каждый угол был круглым. Например, только вверху справа и внизу слева.!