Як зробити вид із закругленими кутами?


94

Я намагаюся зробити вигляд в android із закругленими краями. Рішення, яке я знайшов дотепер, полягає у визначенні фігури із закругленими кутами та використанні її як тла цього виду.

Ось те, що я зробив, визначимо, як малювати, як показано нижче:

<padding
android:top="2dp"
android:bottom="2dp"/>
<corners android:bottomRightRadius="20dp"
android:bottomLeftRadius="20dp"
android:topLeftRadius="20dp"
android:topRightRadius="20dp"/>

Тепер я використав це як фон для мого макета, як показано нижче:

<LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="10dp"
        android:clipChildren="true"
        android:background="@drawable/rounded_corner">

Це працює чудово, я бачу, що вид має закруглені краї.

Але в моєму макеті є багато інших дочірніх поглядів, скажімо ImageView або a MapView. Коли я розміщую ImageViewвсередині вищезазначеного макета, кути зображення не обрізаються / не обрізаються, натомість воно здається заповненим.

Я бачив інші обхідні шляхи, щоб змусити його працювати так, як описано тут .

Але чи існує метод встановлення закруглених кутів для подання, і всі його дочірні види містяться в тому основному поданні, яке має закруглені кути?


Що робити, якщо ви використовуєте спеціальний макет, що розширюється до LinearLayout, і поки його об’єкт створюється, виконуйте ітерацію всіх дочірніх елементів цього макета та застосовуйте до них фон із заокругленими межами?
MysticMagicϡ

3
android.support.v7.widget.CardView, здається, рішення для цього
rocketspacer

Це рішення вирішило це для мене, але вимагає підкласифікації: /programming/5574212/android-view-clipping
Аарон,


Google має нову структуру, нові технології краще [Jetpack Compose] [1] [1]: stackoverflow.com/questions/6054562 / ...
Ucdemir

Відповіді:


128

Інший підхід полягає у створенні власного класу макету, як показано нижче. Цей макет спочатку малює його вміст у позаекранний растровий малюнок, маскує позаекранний растровий малюнок із заокругленим прямокутником, а потім малює позаекранний растровий малюнок на фактичному полотні.

Я спробував, і, здається, це працює (принаймні для мого простого тесту). Звичайно, це вплине на продуктивність порівняно зі звичайним макетом.

package com.example;

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.FrameLayout;

public class RoundedCornerLayout extends FrameLayout {
    private final static float CORNER_RADIUS = 40.0f;

    private Bitmap maskBitmap;
    private Paint paint, maskPaint;
    private float cornerRadius;

    public RoundedCornerLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
        maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

        setWillNotDraw(false);
    }

    @Override
    public void draw(Canvas canvas) {
        Bitmap offscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas offscreenCanvas = new Canvas(offscreenBitmap);

        super.draw(offscreenCanvas);

        if (maskBitmap == null) {
            maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
        }

        offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
        canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
    }

    private Bitmap createMask(int width, int height) {
        Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
        Canvas canvas = new Canvas(mask);

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);

        canvas.drawRect(0, 0, width, height, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);

        return mask;
    }
}

Використовуйте це як звичайний макет:

<com.example.RoundedCornerLayout
    android:layout_width="200dp"
    android:layout_height="200dp">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/test"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#ff0000"
        />

</com.example.RoundedCornerLayout>

1
Я використовую цей макет для перегляду зображень з функцією масштабування всередині, але цей макет не може виявити сенсорний слухач, коли я намагаюся збільшити, як додати функцію сенсорного слухача в цей макет?
Мухаммед Нафіан Вільдана

2
Я використовував цей метод і чудово працює. Але коли я розміщую EditText усередині макета, екран не оновлюється, коли я ввожу текст. Коли я закриваю вікно, текст з’являється на дисплеї. Екран оновлюється після закриття клавіатури. Будь-яке виправлення цього?
Саджиб Ачарія

1
Єдина проблема з цим, коли ви використовуєте його з поданням Recycler, полягає в тому, що він не чекає завантаження повного набору елементів. І округляє лише кілька предметів. Чи є причина для цього?
Ахмед

2
Це не працює із зображеннями, завантаженими з бібліотеки ковзання, які використовують переходи із заповнювачами (або будь-якими іншими анімованими дітьми). У мене є альтернативне рішення, але для цього потрібно, щоб колір тла був однотонним. Дивіться gist.github.com/grennis/da9f86870c45f3b8ae00912edb72e868
Грег Енніс

2
Прекрасне та корисне рішення, але занадто дороге. RecyclerView із лише шістьма елементами, що містить одне зображення, не може прокручуватися плавно. І це не залежить від потужності пристрою (Samsung S9 або Wileyfox Swift 2). stackoverflow.com/a/41098690/4399323 - краща відповідь!
Валентин Юр'єв

73

Або ви можете використовувати android.support.v7.widget.CardViewподібне так:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    card_view:cardBackgroundColor="@color/white"
    card_view:cardCornerRadius="4dp">

    <!--YOUR CONTENT-->
</android.support.v7.widget.CardView>

Я спробував стільки способів, що ваш - найкраще рішення моєї проблеми. ДЯКУЮ!
wizChen

Не вдалося зняти висоту. Відмінно працює, якщо конструкція вимагає піднесення.
Абдалрахман Шату

1
@AbdalrahmanShatou developer.android.com/reference/android/support/v7/widget/... для цього є властивості. Ви намагалися встановити для них значення "0"?
rocketspacer

5
Одним недоліком є ​​те, що він не підтримує <21 android api
Itai Spector

52

shape.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#f6eef1" />

    <stroke
        android:width="2dp"
        android:color="#000000" />

    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />

    <corners android:radius="5dp" />

</shape>

і всередині вас макет

<LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="10dp"
        android:clipChildren="true"
        android:background="@drawable/shape">

        <ImageView
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:src="@drawable/your image"
             android:background="@drawable/shape">

</LinearLayout>

3
@Zach: Яким чином це не спрацювало? Так само, як працював ваш додаток, коли ви задавали оригінальне запитання?
LarsH

2
clipChildren марний, і вигляд зображення все ще виходить за межі зору.
Абдалрахман Шату,

1
Я хотів би дати тобі щедроту за це. Дякую
Одіс

3
Я не думаю, що такий підхід спрацював би, якщо зображення прямокутне, оскільки фон буде намальований за вмістом зображення. Це може працювати лише із зображеннями, які мають прозорість і самі мають закруглені кути.
Харша Вардха

22

Відповідь Яапа ван Хенгстума чудово працює, проте, я вважаю, що це дорого, і якщо ми застосуємо цей метод на кнопці, наприклад, ефект дотику втрачається, оскільки вигляд відображається як растрове зображення.

Для мене найкращий і найпростіший спосіб полягає у застосуванні маски на поданні, наприклад:

@Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
    super.onSizeChanged(width, height, oldWidth, oldHeight);

    float cornerRadius = <whatever_you_want>;
    this.path = new Path();
    this.path.addRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, Path.Direction.CW);
}

@Override
protected void dispatchDraw(Canvas canvas) {
    if (this.path != null) {
        canvas.clipPath(this.path);
    }
    super.dispatchDraw(canvas);
}

Як цим користуватися?
Максим Князєв

@MaksimKniazev Створіть підклас потрібного макета (наприклад: FrameLayout), потім вставте ці два методи в цей підклас і замініть '<wething_you_want>' вашим бажаним значенням радіуса кута (наприклад, з ресурсів). Це воно. Вам це досить ясно чи потрібен приклад?
Віслюк,

Щиро дякую, це справді працює краще для RecyclerView!
Валентин Юр'єв

18

Якщо у вас виникли проблеми під час додавання слухачів до макета. Використовуйте цей макет як батьківський.

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.widget.FrameLayout;

public class RoundedCornerLayout extends FrameLayout {
    private final static float CORNER_RADIUS = 6.0f;
    private float cornerRadius;

    public RoundedCornerLayout(Context context) {
        super(context);
        init(context, null, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }


    @Override
    protected void dispatchDraw(Canvas canvas) {
        int count = canvas.save();

        final Path path = new Path();
        path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), cornerRadius, cornerRadius, Path.Direction.CW);
        canvas.clipPath(path, Region.Op.REPLACE);

        canvas.clipPath(path);
        super.dispatchDraw(canvas);
        canvas.restoreToCount(count);
    }


}

як

<?xml version="1.0" encoding="utf-8"?>
<com.example.view.RoundedCornerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/patentItem"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingRight="20dp">
        ... your child goes here
    </RelativeLayout>
</com.example.view.RoundedCornerLayout>

2
Це добре працює, якщо на екрані не так багато анімації, яка змушує малювати екран знову і знову багато разів; оскільки це критично сповільнить роботу. Спробуйте спробувати cardview, який має ефективний метод кругового кута (не використовувати відсічний контур або canvas.drawRoundRect - погано в API нижче 17, але використовувати porterFilterDuffColor)
Nguyen Tan Dat

18

Створіть файл xml, який називається round.xmlв drawableпапці, і вставте такий вміст:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <solid android:color="#FFFFFF" />
  <stroke android:width=".05dp" android:color="#d2d2d2" />
  <corners android:topLeftRadius="5dp" android:topRightRadius="5dp" android:bottomRightRadius="5dp" android:bottomLeftRadius="5dp"/>
</shape>

потім використовуйте round.xmlяк backgroundдля будь-якого елемента. Тоді це дасть вам закруглені кути.


9

В Android L ви зможете просто використовувати View.setClipToOutline, щоб отримати такий ефект. У попередніх версіях немає можливості просто відрізати вміст випадкової групи перегляду у певній формі.

Вам доведеться придумати щось, що могло б дати вам подібний ефект:

  • Якщо вам потрібні лише закруглені кути в ImageView, ви можете використовувати шейдер, щоб «намалювати» зображення над формою, яку ви використовуєте як фон. Для прикладу погляньте на цю бібліотеку .

  • Якщо вам дійсно потрібно, щоб усі діти були відрізані, можливо, ви можете переглянути інший вид вашого макета? Такий із фоном будь-якого кольору, який ви використовуєте, і круглою «діркою» посередині? Ви насправді можете створити власну ViewGroup, яка малює таку форму для кожної дитини, перевизначуючи метод onDraw.


4

Створіть xml-файл у папці, яку можна малювати, з наступним кодом. (Ім'я створеного мною файлу округлене_корнер.xml)

rounded_corner.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="#a9c5ac" >
        </solid>

        <!-- view border color and width -->
        <stroke
            android:width="3dp"
            android:color="#1c1b20" >
        </stroke>

        <!-- If you want to add some padding -->
        <padding
            android:left="4dp"
            android:top="4dp"
            android:right="4dp"
            android:bottom="4dp"    >
        </padding>

        <!-- Here is the corner radius -->
        <corners
            android:radius="10dp"   >
        </corners>
    </shape>

І зберігайте це drawableяк backgroundдля виду, до якого ви хочете зберегти закруглений кутовий кордон. Давайте збережемо це для aLinearLayout

    <LinearLayout android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/rounded_corner"
            android:layout_centerInParent="true">

            <TextView android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Hi, This layout has rounded corner borders ..."
                android:gravity="center"
                android:padding="5dp"/>

    </LinearLayout>

3

дотримуйтесь цього підручника та всіх обговорень під ним - http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/

згідно з цим дописом, написаним Гаєм Роменом, одним з провідних розробників цілого набору інструментів для користувальницького інтерфейсу Android, можна зробити контейнер (і всі його погляди дитини) із закругленими кутами, але він пояснив, що це занадто дорого (з виступів проблеми з візуалізацією).

Я порекомендую вам піти відповідно до його посади, і якщо ви хочете закруглені кути, то застосуйте закруглені кути ImageView відповідно до цієї публікації. тоді ви можете помістити його всередину контейнера з будь-яким фоном, і ви отримаєте бажаний ефект.

це те, що я зробив також, врешті-решт.


3

Ви можете використовувати androidx.cardview.widget.CardViewподібне так:

<androidx.cardview.widget.CardView
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="wrap_content"       
        app:cardCornerRadius="@dimen/dimen_4"
        app:cardElevation="@dimen/dimen_4"
        app:contentPadding="@dimen/dimen_10">

       ...

</androidx.cardview.widget.CardView>

АБО

shape.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#f6eef1" />

    <stroke
        android:width="2dp"
        android:color="#000000" />

    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />

    <corners android:radius="5dp" />

</shape>

і всередині вас макет

<LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shape">

        ...

</LinearLayout>

3

У CardViewмене це працювало в API 27 в Android Studio 3.0.1. На файл colorPrimaryбуло res/values/colors.xmlвказано посилання, і це лише приклад. Для layout_width 0dpвона розтягнеться на ширину батьківської. Вам доведеться налаштувати обмеження та ширину / висоту відповідно до ваших потреб.

<android.support.v7.widget.CardView
    android:id="@+id/cardView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:cardCornerRadius="4dp"
    app:cardBackgroundColor="@color/colorPrimary">

    <!-- put your content here -->

</android.support.v7.widget.CardView>

3

У бібліотеці компонентів матеріалів найкращим способом зробити a Viewіз закругленими кутами є використання MaterialShapeDrawable.

Створіть ShapeAppearanceModel із спеціальними закругленими кутами:

ShapeAppearanceModel shapeAppearanceModelLL1 = new ShapeAppearanceModel()
        .toBuilder()
        .setAllCorners(CornerFamily.ROUNDED,radius16)
        .build();

Створіть MaterialShapeDrawable:

MaterialShapeDrawable shapeDrawableLL1 = new MaterialShapeDrawable(shapeAppearanceModeLL1);

Якщо ви хочете застосувати також elevationOverlay для темної теми, використовуйте це:

MaterialShapeDrawable shapeDrawableLL1 = MaterialShapeDrawable.createWithElevationOverlay(this, 4.0f);
shapeDrawableLL1.setShapeAppearanceModel(shapeAppearanceModelLL1);

Необов’язково: застосувати до фігури Малюнок кольором тла та штрихом

shapeDrawableLL1.setFillColor(
       ContextCompat.getColorStateList(this,R.color...));
 shapeDrawableLL1.setStrokeWidth(2.0f);
 shapeDrawableLL1.setStrokeColor(
       ContextCompat.getColorStateList(this,R.color...));

Нарешті застосуйте shapeDrawable як фон у вашому LinearLayout(або іншому поданні):

LinearLayout linearLayout1= findViewById(R.id.ll_1);
ViewCompat.setBackground(linearLayout1,shapeDrawableLL1);

введіть тут опис зображення


2

Відмінність від відповіді Яапа ван Хенгстума:

  1. Використовуйте BitmapShader замість растрового зображення.
  2. Створити растрове зображення лише один раз.
public class RoundedFrameLayout extends FrameLayout {
    private Bitmap mOffscreenBitmap;
    private Canvas mOffscreenCanvas;
    private BitmapShader mBitmapShader;
    private Paint mPaint;
    private RectF mRectF;

    public RoundedFrameLayout(Context context) {
        super(context);
        init();
    }

    public RoundedFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RoundedFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setWillNotDraw(false);
    }

    @Override
    public void draw(Canvas canvas) {
        if (mOffscreenBitmap == null) {
            mOffscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
            mOffscreenCanvas = new Canvas(mOffscreenBitmap);
            mBitmapShader = new BitmapShader(mOffscreenBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setShader(mBitmapShader);
            mRectF = new RectF(0f, 0f, canvas.getWidth(), canvas.getHeight());
        }
        super.draw(mOffscreenCanvas);

        canvas.drawRoundRect(mRectF, 8, 8, mPaint);
    }
}

2
public class RoundedCornerLayout extends FrameLayout {
    private double mCornerRadius;

    public RoundedCornerLayout(Context context) {
        this(context, null, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    public double getCornerRadius() {
        return mCornerRadius;
    }

    public void setCornerRadius(double cornerRadius) {
        mCornerRadius = cornerRadius;
    }

    @Override
    public void draw(Canvas canvas) {
        int count = canvas.save();

        final Path path = new Path();
        path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight()), (float) mCornerRadius, (float) mCornerRadius, Path.Direction.CW);
        canvas.clipPath(path, Region.Op.REPLACE);

        canvas.clipPath(path);
        super.draw(canvas);
        canvas.restoreToCount(count);
    }
}

1

Здається, що посилання підручника, яке ви надали, передбачає, що вам потрібно встановити властивості layout_width і layout_height для ваших дочірніх елементів на match_parent.

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

1

Щоб створити кругле кутове зображення, використовуючи com.google.android.material: material: 1.2.0-beta01

 float radius = context.getResources().getDimension(R.dimen.border_radius_hug);
    shapeAppearanceModel = new ShapeAppearanceModel()
            .toBuilder()
            .setAllCorners(CornerFamily.ROUNDED,radius)
            .build();

imageView.setShapeAppearanceModel(shapeAppearanceModel)

або якщо ви хочете використовувати його у файлі xml:

  <com.google.android.material.imageview.ShapeableImageView
            android:id="@+id/thumb"
            android:layout_width="80dp"
            android:layout_height="60dp"
            app:shapeAppearanceOverlay="@style/circleImageView"
            />

у style.xml додайте це:

<style name="circleImageView" parent="">
      <item name="cornerFamily">rounded</item>
      <item name="cornerSize">10%</item>
</style>

0

спробуйте цю властивість з вашим лінійним макетом, це допоможе
інструментам: context = ". youractivity"


0
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {

        Bitmap roundedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(roundedBitmap);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return roundedBitmap;
    }

0

На випадок, якщо ви хочете обійти якийсь конкретний кут.

fun setCorners() {
        
        val mOutlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View, outline: Outline) {

                val left = 0
                val top = 0;
                val right = view.width
                val bottom = view.height
                val cornerRadiusDP = 16f
                val cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, cornerRadiusDP, resources.displayMetrics).toInt()

                // all corners
                outline.setRoundRect(left, top, right, bottom, cornerRadius.toFloat())

                /* top corners
                outline.setRoundRect(left, top, right, bottom+cornerRadius, cornerRadius.toFloat())*/

                /* bottom corners
                outline.setRoundRect(left, top - cornerRadius, right, bottom, cornerRadius.toFloat())*/

                /* left corners
                outline.setRoundRect(left, top, right + cornerRadius, bottom, cornerRadius.toFloat())*/

                /* right corners
                outline.setRoundRect(left - cornerRadius, top, right, bottom, cornerRadius.toFloat())*/

                /* top left corner
                outline.setRoundRect(left , top, right+ cornerRadius, bottom + cornerRadius, cornerRadius.toFloat())*/

                /* top right corner
                outline.setRoundRect(left - cornerRadius , top, right, bottom + cornerRadius, cornerRadius.toFloat())*/

                /* bottom left corner
                outline.setRoundRect(left, top - cornerRadius, right + cornerRadius, bottom, cornerRadius.toFloat())*/

                /* bottom right corner
                outline.setRoundRect(left - cornerRadius, top - cornerRadius, right, bottom, cornerRadius.toFloat())*/

            }
        }

        myView.apply {
            outlineProvider = mOutlineProvider
            clipToOutline = true
        }
    }

-1

Використовуйте фігуру в xml із прямокутником. Встановіть властивість нижнього або верхнього радіуса, як хочете. Потім застосуйте цей xml як фон для перегляду ur .... або ... використовуйте градієнти, щоб зробити це з коду.


Я вже це робив, але хочу знати, чи є кращий метод?
Зак,

Запитувач вже згадував про спробу такого підходу у своєму питанні.
Michael Krause
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.