ImageView w kółku przez xml

201

Chciałbym, aby każdy obraz z mojego ImageViewbył okrągły z ramką.

Szukałem, ale nie mogłem znaleźć żadnych przydatnych informacji (nic, co próbowałem, nie zadziałało).

Jak mogę to osiągnąć przez xml: Utwórz plik ImageViewz pewnym kodem src i ustaw go tak, aby był okrągły z ramką?

użytkownik3050910
źródło
Jak zmienić src ImageView w kodzie Java?
chenzhongpu
Dobre proste rozwiązanie tutaj stackoverflow.com/a/28096369/2162226 - wszystko w Javie, dzięki czemu możesz dynamicznie zastosować to formatowanie do obrazów w środowisku wykonawczym
Gene Bo
Musisz umieścić ImageView wewnątrz CardView, ponieważ CardView ma tylko funkcję dostępu do atrybutu promienia narożnika.
Vahag Chakhoyan

Odpowiedzi:

221

Możesz zrobić prosty okrąg z białą ramką i przezroczystą zawartością o kształcie.

// res/drawable/circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadius="0dp"
    android:shape="ring"
    android:thicknessRatio="1.9"
    android:useLevel="false" >
    <solid android:color="@android:color/transparent" />

    <stroke
        android:width="10dp"
        android:color="@android:color/white" />
</shape>

Następnie ustaw listę warstw do rysowania i umieść ją jako tło do podglądu obrazu.

// res/drawable/img.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:drawable="@drawable/circle"/>    
    <item android:drawable="@drawable/ic_launcher"/>

</layer-list>

i umieść to jako tło do podglądu obrazu.

   <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/img"/>

Będziesz miał coś takiego.

wprowadź opis zdjęcia tutaj

Orhan Obut
źródło
13
A potem ustawiłem ten kształt na tle mojego podglądu obrazu? Próbowałem tego, ale nie działało. Mój obraz wciąż jest prostokątny :(
user3050910
3
tak, używając XML, ponieważ korzystanie z kodu Java jest bardzo kosztowne dla urządzeń mobilnych. Z tym kodem pojawia się tylko koło za moim obrazem, a nie sam obraz jest kołem. Przypuszczam, że jest na granicy, chcę, aby obraz był zaokrąglony w kręgu w tym
user3050910
5
Ale wciąż coś jest nie tak. Poza tym obraz ma okrągłą ramkę z przodu, nie jest przezroczysty poza okręgiem. To znaczy, koło jest tam, jednak rogi obrazu są widoczne i wykraczają poza obszar koła za nim
user3050910
79
Jak zmienić src ImageView w kodzie Java, jeśli przejdę w ten sposób?
chenzhongpu
3
bezużyteczne, zapisane na stałe źródło img, chciałbym zmienić za pomocą kodu
user924
290

To najprostszy sposób, który zaprojektowałem. Spróbuj tego.

dependencies: compile 'com.android.support:appcompat-v7:23.1.1'
              compile 'com.android.support:design:23.1.1'
              compile 'com.android.support:cardview-v7:23.1.1'

<android.support.v7.widget.CardView
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:elevation="12dp"
    android:id="@+id/view2"
   app:cardCornerRadius="40dp"
    android:layout_centerHorizontal="true"
    android:innerRadius="0dp"
    android:shape="ring"
    android:thicknessRatio="1.9">
    <ImageView
        android:layout_height="80dp"
        android:layout_width="match_parent"
        android:id="@+id/imageView1"
        android:src="@drawable/YOUR_IMAGE"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true">
    </ImageView>
 </android.support.v7.widget.CardView>

Jeśli pracujesz na wersjach Androida powyżej Lollipop

<android.support.v7.widget.CardView
android:layout_width="80dp"
android:layout_height="80dp"
android:elevation="12dp"
android:id="@+id/view2"
app:cardCornerRadius="40dp"
android:layout_centerHorizontal="true">
<ImageView
    android:layout_height="80dp"
    android:layout_width="match_parent"
    android:id="@+id/imageView1"
    android:src="@drawable/YOUR_IMAGE"
    android:scaleType="centerCrop"/>
  </android.support.v7.widget.CardView>

Dodawanie obramowania do okrągłego ImageView - NAJNOWSZA WERSJA

Owiń go innym CardView nieco większym niż wewnętrzny i ustaw kolor tła, aby dodać obramowanie do okrągłego obrazu. Możesz zwiększyć rozmiar zewnętrznego CardView, aby zwiększyć grubość ramki.

<androidx.cardview.widget.CardView
  android:layout_width="155dp"
  android:layout_height="155dp"
  app:cardCornerRadius="250dp"
  app:cardBackgroundColor="@color/white">

    <androidx.cardview.widget.CardView
      android:layout_width="150dp"
      android:layout_height="150dp"
      app:cardCornerRadius="250dp"
      android:layout_gravity="center">

        <ImageView
          android:layout_width="150dp"
          android:layout_height="150dp"
          android:src="@drawable/default_user"
          android:scaleType="centerCrop"/>

   </androidx.cardview.widget.CardView>

 </androidx.cardview.widget.CardView>
shreedhar bhat
źródło
1
Dzięki za to. Proste i łatwe użycie pamięci. Wszystkie biblioteki, które wypróbowałem do tej pory, dają wyjątki OOME podczas używania widoków niestandardowych w elementach RecyclerView.
COBB
11
Próbowałem tego użyć, wygląda na to, że nie działa z Androidem poniżej 5.0. Mimo że widok obrazu jest okrągły, obrazy są mniejsze i mają kwadratowy kształt, wyglądają okropnie. Jakieś sugestie? 5.0 i wyżej działa dobrze.
Kaps
6
mój obraz nie pasuje do CardView przy użyciu tej metody
Hendra Anggrian
21
Powoduje to, że widok karty jest zaokrąglony, ale obraz jest nadal kwadratowy poniżej
kabuto178
5
Dzięki, klucz tutaj jest, że promień karty musi wynosić połowę szerokości i wysokości, aby zrobić właściwe koło.
B.shruti
124

Mam nadzieję, że to Ci pomoże.

1) CircleImageView

wprowadź opis zdjęcia tutaj

 <de.hdodenhof.circleimageview.CircleImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/profile_image"
    android:layout_width="96dp"
    android:layout_height="96dp"
    android:src="@drawable/profile"
    app:civ_border_width="2dp"
    app:civ_border_color="#FF000000"/>

Nie zapomnij o implementacji: Gradle Scripts> build.gradle (Module: app)> zależności

     implementation 'de.hdodenhof:circleimageview:3.1.0'   

Pełny opis można znaleźć tutaj: Źródło tutaj.

2) CircularImageView

wprowadź opis zdjęcia tutaj

<com.mikhaellopez.circularimageview.CircularImageView
    android:layout_width="250dp"
    android:layout_height="250dp"
    android:src="@drawable/image"
    app:civ_border_color="#3f51b5"
    app:civ_border_width="4dp"
    app:civ_shadow="true"
    app:civ_shadow_radius="10"
    app:civ_shadow_color="#3f51b5"/>

Nie zapomnij o implementacji: Gradle Scripts> build.gradle (Module: app)> zależności

     implementation 'com.mikhaellopez:circularimageview:4.2.0'   

Pełny opis można znaleźć tutaj: Źródło tutaj.

Sanjay Mangaroliya
źródło
1
Jak zmienić część w kolorze szarym na biały?
John Joe,
2
Od czasu opublikowania aktualizacji. zmieniono nazwę border_colour i border_width. Sprawdź stronę github, aby uzyskać więcej informacji: github.com/hdodenhof/CircleImageView
rharvey 21.09.16
Nie obsługuje typu skali. :(
Khan
cześć działa dobrze, gdy ustawia się za pomocą src, ale jego zachowanie jest inne, gdy próbuje się ustawić za pomocą kodu Java
Erum
@Erum Musisz po prostu umieścić kompilację „de.hdodenhof: circleimageview: 1.3.0” w pliku stopni, nie potrzebujesz kodu Java.
Sanjay Mangaroliya
46

Za pomocą biblioteki glide i klasy RoundedBitmapDrawableFactory można to łatwo osiągnąć. Może być konieczne utworzenie okrągłego obrazu zastępczego.

Glide V4:

Glide.with(context).load(url).apply(RequestOptions.circleCropTransform()).into(imageView);

Glide V3:

    Glide.with(context)
        .load(imgUrl)
        .asBitmap()
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.placeholder)
        .into(new BitmapImageViewTarget(imgProfilePicture) {
            @Override
            protected void setResource(Bitmap resource) {
                RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
                        Bitmap.createScaledBitmap(resource, 50, 50, false));
                drawable.setCircular(true);
                imgProfilePicture.setImageDrawable(drawable);
            }
        });

W przypadku Picasso RoundedTransformation jest to naprawdę świetne rozwiązanie, które daje dodatkową opcję zaokrąglania obrazu na górnej lub dolnej krawędzi.

Chitrang
źródło
2
Nie jestem pewien, jakiej wersji glide używasz w tym przykładzie, ale w wersji 4.0.0 możesz po prostu użyć ich RequestOptions zamiast RoundedBitmapDrawable: Glide.with(context).load(imgUrl).apply(new RequestOptions().centerCrop()) .into(imageView)
Eugene Brusov
2
Nie masz na myśli; Glide.with (context) .load (imgUrl) .apply (new RequestOptions (). CircleCrop ()) .into (imageView)?
Androidz
3
Z wersją 4.6.1.apply(RequestOptions.circleCropTransform())
Pavel
2
W Glide v.4 jeśli GlideAppjest skonfigurowana w aplikacji: GlideApp.with(this).load(url).circleCrop().into(imageView);.
CoolMind
1
Nie mogę uwierzyć, że działało to tak łatwo bez problemów
Ajeeli
30

Powyższe metody nie działają, jeśli używasz srcatrybutu. To, co zrobiłem, to umieszczenie dwóch widoków obrazu w układzie ramki jeden nad drugim w ten sposób:

<FrameLayout android:id="@+id/frame"
             android:layout_width="40dp"
             android:layout_height="40dp">

    <ImageView android:id="@+id/pic"
               android:layout_width="40dp"
               android:layout_height="40dp"
               android:src="@drawable/my_picture" />

    <ImageView android:id="@+id/circle_crop"
               android:layout_width="40dp"
               android:layout_height="40dp"
               android:src="@drawable/circle_crop" />

</FrameLayout>

Po prostu włóż okrągły_krop.png do folderu, który można wyciągnąć, który ma kształt wymiarów obrazu (w moim przypadku kwadrat) z białym tłem i przezroczystym okręgiem pośrodku. Możesz użyć tego obrazu, jeśli chcesz mieć kwadratowy widok obrazu.

Okrągły obraz

Wystarczy pobrać zdjęcie powyżej.

Jyotman Singh
źródło
2
najlepsze rozwiązanie! najlepsza wydajność. zmiana mapy bitowej to problem z pamięcią
itzhar
Ten przykładowy obraz jest biały, więc tak. Ale możesz stworzyć własny obraz w dowolnym kolorze lub pobrać ten obraz i po prostu zmienić jego kolor.
Jyotman Singh,
Czy możesz wyjaśnić, w jaki sposób mogę zmienić kolor obrazu na czarny? czy można to zrobić z poziomu Android Studio, czy też potrzebuję zewnętrznego narzędzia (widać, że nie jestem zaznajomiony z tworzeniem obrazów)
Zvi
Nie, nie z poziomu Android Studio. Potrzebujesz czegoś takiego jak Photoshop. To samo zdjęcie zostało również utworzone w Photoshopie
Jyotman Singh
1
Możesz po prostu nadać okręgowi rysowalnego filtr kolorów: circleCrop.setColorFilter (getResources (). GetColor (R.color.white)). W ten sposób możesz mieć jedno koło do rysowania w dowolnym kolorze i ponownie użyć go w dowolnym miejscu w aplikacji na dowolnym tle. Wystarczy za każdym razem ustawić filtr kolorów z odpowiednim zasobem kolorów.
mjp66
19

Oto jeden z najprostszych sposobów, aby to zrobić, użyj następującego kodu:

Zależności

dependencies {
    ...
    compile 'de.hdodenhof:circleimageview:2.1.0'      // use this or use the latest compile version. In case u get bug.
}

Kod XML

<de.hdodenhof.circleimageview.CircleImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/profile_image"
    android:layout_width="96dp"             //  here u can adjust the width 
    android:layout_height="96dp"            //  here u can adjust the height 
    android:src="@drawable/profile"         //  here u can change the image 
    app:civ_border_width="2dp"              //  here u can adjust the border of the circle.  
    app:civ_border_color="#FF000000"/>      //  here u can adjust the border color

Zrzut ekranu:

Zrzut ekranu

Źródło: Circular ImageView GitHub Repository

wprowadź opis zdjęcia tutaj

Błędy Buggy
źródło
6
Nie obsługuje typu skali. :(
Khan
6

To załatwi sprawę:

rectangle.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/transparent" />
    <padding android:bottom="-14dp" android:left="-14dp" android:right="-14dp" android:top="-14dp" />

</shape>

circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadius="0dp"
    android:shape="oval"

    android:useLevel="false" >
    <solid android:color="@android:color/transparent" />

    <stroke
        android:width="15dp"
        android:color="@color/verification_contact_background" />

</shape>

profile_image.xml (lista warstw)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:drawable="@drawable/rectangle" />
    <item android:drawable="@drawable/circle"/>

</layer-list>

Twój układ

 <ImageView
        android:id="@+id/profile_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/default_org"
        android:src="@drawable/profile_image"/>
Nidhi
źródło
co to jest default_org?
John Joe
może to być dowolny obraz zastępczy
Nidhi
w takim przypadku krawędzie obrazu o wymiarze prostokątnym przekroczą granice koła. Jak mogę dokładnie ustawić każdy obraz, w każdym wymiarze i formie, wewnątrz okręgu?
inverted_index
6

Wystarczy użyć ShapeableImageViewdostarczonej przez bibliotekę komponentów materiałów.
Coś jak:

<com.google.android.material.imageview.ShapeableImageView
    app:shapeAppearanceOverlay="@style/roundedImageViewRounded"
    app:strokeColor="@color/....."
    app:strokeWidth="1dp"
    ...
    />

z:

  <style name="roundedImageViewRounded">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">50%</item>
  </style>

wprowadź opis zdjęcia tutaj

Uwaga: wymaga co najmniej wersji 1.2.0-alpha03.

Gabriele Mariotti
źródło
5

Możesz po prostu użyć CardView bez żadnej zewnętrznej biblioteki

  <androidx.cardview.widget.CardView
                    android:id="@+id/roundCardView"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_centerHorizontal="true"
                    android:elevation="0dp"
                    app:cardCornerRadius="20dp">

                    <ImageView
                        android:layout_width="40dp"
                        android:layout_height="40dp"
                        android:src="@drawable/profile" />
</androidx.cardview.widget.CardView>
Abdurahman Popal
źródło
4

Używam shape = „oval” zamiast „ring” poniżej. To zadziałało dla mnie. Aby utrzymać obraz w granicach, używam <padding>i ustawiam <adjustViewBounds>na true <ImageView>. Próbowałem z obrazami o wielkości od 50 x 50 pikseli do 200 x 200 pikseli.

Subramanya Sheshadri
źródło
Możesz również dodać następujące elementyandroid:scaleType="fitCenter"
ihayet
2

@Jotman Singh, odpowiedź jest bardzo dobra (dla jednolitych środowisk), dlatego chciałbym ją ulepszyć, udostępniając wektor do rysowania, który można ponownie pokolorować według potrzeb, jest to również wygodne, ponieważ jednoczęściowy kształt wektorowy jest dobrze skalowalny.

To jest kształt koła prostokątnego (@ drawable / shape_round_profile_pic):

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:viewportWidth="284"
    android:viewportHeight="284"
    android:width="284dp"
    android:height="284dp">
    <path
        android:pathData="M0 142L0 0l142 0 142 0 0 142 0 142 -142 0 -142 0zm165 137.34231c26.06742 -4.1212 52.67405 -17.543 72.66855 -36.65787 11.82805 -11.30768 20.55487 -22.85153 27.7633 -36.72531C290.23789 158.21592 285.62874 101.14121 253.48951 58.078079 217.58149 9.9651706 154.68849 -10.125717 98.348685 8.5190299 48.695824 24.95084 12.527764 67.047123 3.437787 118.98655 1.4806194 130.16966 1.511302 152.96723 3.4990422 164.5 12.168375 214.79902 47.646316 256.70775 96 273.76783c21.72002 7.66322 44.26673 9.48476 69 5.57448z"
        android:fillColor="#ffffff" /> // you can change frame color
</vector>

Użycie jest takie samo:

<FrameLayout
        android:layout_width="70dp"
        android:layout_height="70dp">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/YOUR_PICTURE" />

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/shape_round_profile_pic"/>

    </FrameLayout>
ekar
źródło
A jak to ma działać? Po prostu wyświetlasz okrąg nad obrazem, a tak naprawdę pytasz, jak przyciąć obraz, aby wyglądał jak koło.
Fattum
Zobacz odpowiedź @Jyotman Singh powyżej. Było to dla mnie pomocne, więc trochę go ulepszyłem. Aby przyciąć obraz, możesz użyć:GlideApp.with(getApplicationContext()).asBitmap().load(profilePhotoUrl) .circleCrop()
ekar
Dziękujemy za kształt koła w prostokącie! Dokładnie to, czego potrzebowałem!
siralexsir88
2

Wystarczy użyć tych wierszy kodu i gotowe:

<de.hdodenhof.circleimageview.CircleImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:clickable="true"
            app:civ_border_width="3dp"
            app:civ_border_color="#FFFFFFFF"
            android:id="@+id/profile"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_below="@+id/header_cover_image"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="-130dp"
            android:elevation="5dp"
            android:padding="20dp"
            android:scaleType="centerCrop"
            android:src="@drawable/profilemain" />

wprowadź opis zdjęcia tutaj

Nie zapomnij zaimportować:

import de.hdodenhof.circleimageview.CircleImageView;

Dodaj tę bibliotekę w build.gradle:

compile 'de.hdodenhof:circleimageview:2.1.0'
Hanisha
źródło
musisz coś przegapić w klasie java
John Joe
1

Spróbuj tego.

public class RoundedImageView extends android.support.v7.widget.AppCompatImageView {

    private int borderWidth = 4;
    private int viewWidth;
    private int viewHeight;
    private Bitmap image;
    private Paint paint;
    private Paint paintBorder;
    private BitmapShader shader;

    public RoundedImageView(Context context)
    {
        super(context);
        setup();
    }

    public RoundedImageView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        setup();
    }

    public RoundedImageView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        setup();
    }

    private void setup()
    {
        paint = new Paint();
        paint.setAntiAlias(true);

        paintBorder = new Paint();
        setBorderColor(Color.WHITE);
        paintBorder.setAntiAlias(true);
        this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);

        paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.WHITE);
    }

    public void setBorderWidth(int borderWidth)
    {
        this.borderWidth = borderWidth;
        this.invalidate();
    }

    public void setBorderColor(int borderColor)
    {
        if (paintBorder != null)
            paintBorder.setColor(borderColor);

        this.invalidate();
    }

    private void loadBitmap()
    {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();

        if (bitmapDrawable != null)
            image = bitmapDrawable.getBitmap();
    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas)
    {
        loadBitmap();

        if (image != null)
        {
            shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint.setShader(shader);
            int circleCenter = viewWidth / 2;
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder);
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, paint);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec, widthMeasureSpec);

        viewWidth = width - (borderWidth * 2);
        viewHeight = height - (borderWidth * 2);

        setMeasuredDimension(width, height);
    }

    private int measureWidth(int measureSpec)
    {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY)
        {
            result = specSize;
        }
        else
        {
            // Measure the text
            result = viewWidth;
        }

        return result;
    }

    private int measureHeight(int measureSpecHeight, int measureSpecWidth)
    {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpecHeight);
        int specSize = MeasureSpec.getSize(measureSpecHeight);

        if (specMode == MeasureSpec.EXACTLY)
        {
            result = specSize;
        }
        else
        {
            result = viewHeight;
        }

        return (result + 2);
     }
 }

i użyj tego ImageView w układzie takim jak:

<com.app.Demo.RoundedImageView
     android:id="@+id/iv_profileImage"
     android:layout_width="70dp"
     android:layout_height="70dp"
     android:layout_centerHorizontal="true"
    />
NipunPerfect
źródło
1

Jeśli używasz Material Design w swojej aplikacji, użyj tego

<com.google.android.material.card.MaterialCardView
            android:layout_width="75dp"
            android:layout_height="75dp"
            app:cardCornerRadius="50dp"
            app:strokeWidth="1dp"
            app:strokeColor="@color/black">
            <ImageView
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:id="@+id/circular_image"
                android:scaleType="fitCenter"
                android:src="@drawable/your_img" />
        </com.google.android.material.card.MaterialCardView>
Izhan Ali
źródło
0

Ta klasa to niestandardowy okrągły widok obrazu z cieniem, obrysem, nasyceniem i za pomocą tego niestandardowego okrągłego obrazu można uzyskać obraz w okrągłym kształcie z promieniem. Faceci dla Circular Shadow ImageView Nie ma potrzeby Github tej klasy wystarczy.

Dodawanie CircularImageView do układu

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" />
dileep krishnan
źródło
0

W rzeczywistości możesz korzystać z tego, co zapewnia Google za pośrednictwem biblioteki wsparcia Klasa RoundedBitmapDrawableFactory ( tu i tutaj zamiast ), zamiast używać biblioteki innej firmy:

Stopień:

implementation 'androidx.appcompat:appcompat:1.0.0-beta01'

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val originalDrawable = ContextCompat.getDrawable(this, R.drawable.avatar_1)!!
        val bitmap = convertDrawableToBitmap(originalDrawable)
        val drawable = RoundedBitmapDrawableFactory.create(resources, bitmap)
        drawable.setAntiAlias(true)
        drawable.cornerRadius = Math.max(bitmap.width, bitmap.height) / 2.0f
        avatarImageView.setImageDrawable(drawable)
    }

    companion object {
        @JvmStatic
        fun convertDrawableToBitmap(drawable: Drawable): Bitmap {
            if (drawable is BitmapDrawable)
                return drawable.bitmap
            // We ask for the bounds if they have been set as they would be most
            // correct, then we check we are  > 0
            val bounds = drawable.bounds
            val width = if (!bounds.isEmpty) bounds.width() else drawable.intrinsicWidth
            val height = if (!bounds.isEmpty) bounds.height() else drawable.intrinsicHeight
            // Now we check we are > 0
            val bitmap = Bitmap.createBitmap(if (width <= 0) 1 else width, if (height <= 0) 1 else height,
                    Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            drawable.setBounds(0, 0, canvas.width, canvas.height)
            drawable.draw(canvas)
            return bitmap
        }
    }
}

res / layout / activity_main.xml

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity">

    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/avatarImageView" android:layout_width="100dp" android:layout_height="100dp"
        android:layout_gravity="center"/>

</FrameLayout>

res / drawable / avatar_1.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="128dp" android:height="128dp"
        android:viewportHeight="128.0" android:viewportWidth="128.0">
    <path
        android:fillColor="#FF8A80" android:pathData="M0 0h128v128h-128z"/>
    <path
        android:fillColor="#FFE0B2"
        android:pathData="M36.3 94.8c6.4 7.3 16.2 12.1 27.3 12.4 10.7,-.3 20.3,-4.7 26.7,-11.6l.2.1c-17,-13.3,-12.9,-23.4,-8.5,-28.6 1.3,-1.2 2.8,-2.5 4.4,-3.9l13.1,-11c1.5,-1.2 2.6,-3 2.9,-5.1.6,-4.4,-2.5,-8.4,-6.9,-9.1,-1.5,-.2,-3 0,-4.3.6,-.3,-1.3,-.4,-2.7,-1.6,-3.5,-1.4,-.9,-2.8,-1.7,-4.2,-2.5,-7.1,-3.9,-14.9,-6.6,-23,-7.9,-5.4,-.9,-11,-1.2,-16.1.7,-3.3 1.2,-6.1 3.2,-8.7 5.6,-1.3 1.2,-2.5 2.4,-3.7 3.7l-1.8 1.9c-.3.3,-.5.6,-.8.8,-.1.1,-.2 0,-.4.2.1.2.1.5.1.6,-1,-.3,-2.1,-.4,-3.2,-.2,-4.4.6,-7.5 4.7,-6.9 9.1.3 2.1 1.3 3.8 2.8 5.1l11 9.3c1.8 1.5 3.3 3.8 4.6 5.7 1.5 2.3 2.8 4.9 3.5 7.6 1.7 6.8,-.8 13.4,-5.4 18.4,-.5.6,-1.1 1,-1.4 1.7,-.2.6,-.4 1.3,-.6 2,-.4 1.5,-.5 3.1,-.3 4.6.4 3.1 1.8 6.1 4.1 8.2 3.3 3 8 4 12.4 4.5 5.2.6 10.5.7 15.7.2 4.5,-.4 9.1,-1.2 13,-3.4 5.6,-3.1 9.6,-8.9 10.5,-15.2m-14.4,-49.8c.9 0 1.6.7 1.6 1.6 0 .9,-.7 1.6,-1.6 1.6,-.9 0,-1.6,-.7,-1.6,-1.6,-.1,-.9.7,-1.6 1.6,-1.6zm-25.7 0c.9 0 1.6.7 1.6 1.6 0 .9,-.7 1.6,-1.6 1.6,-.9 0,-1.6,-.7,-1.6,-1.6,-.1,-.9.7,-1.6 1.6,-1.6z"/>
    <path
        android:fillColor="#E0F7FA"
        android:pathData="M105.3 106.1c-.9,-1.3,-1.3,-1.9,-1.3,-1.9l-.2,-.3c-.6,-.9,-1.2,-1.7,-1.9,-2.4,-3.2,-3.5,-7.3,-5.4,-11.4,-5.7 0 0 .1 0 .1.1l-.2,-.1c-6.4 6.9,-16 11.3,-26.7 11.6,-11.2,-.3,-21.1,-5.1,-27.5,-12.6,-.1.2,-.2.4,-.2.5,-3.1.9,-6 2.7,-8.4 5.4l-.2.2s-.5.6,-1.5 1.7c-.9 1.1,-2.2 2.6,-3.7 4.5,-3.1 3.9,-7.2 9.5,-11.7 16.6,-.9 1.4,-1.7 2.8,-2.6 4.3h109.6c-3.4,-7.1,-6.5,-12.8,-8.9,-16.9,-1.5,-2.2,-2.6,-3.8,-3.3,-5z"/>
    <path
        android:fillColor="#444" android:pathData="M76.3,47.5 m-2.0, 0 a 2.0,2.0 0 1,1 4.0,0 a2.0,2.0 0 1,1 -4.0,0"/>
    <path
        android:fillColor="#444" android:pathData="M50.7,47.6 m-2.0, 0 a 2.0,2.0 0 1,1 4.0,0 a2.0,2.0 0 1,1 -4.0,0"/>
    <path
        android:fillColor="#444"
        android:pathData="M48.1 27.4c4.5 5.9 15.5 12.1 42.4 8.4,-2.2,-6.9,-6.8,-12.6,-12.6,-16.4 17.2 1.5 14.1,-9.4 14.1,-9.4,-1.4 5.5,-11.1 4.4,-11.1 4.4h-18.8c-1.7,-.1,-3.4 0,-5.2.3,-12.8 1.8,-22.6 11.1,-25.7 22.9 10.6,-1.9 15.3,-7.6 16.9,-10.2z"/>
</vector>

Wynik:

wprowadź opis zdjęcia tutaj

Załóżmy, że chcesz dodać na nim ramkę, możesz użyć tego na przykład:

stroke_drawable.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <stroke
        android:width="4dp" android:color="@android:color/black"/>
</shape>

I dodaj android:foreground="@drawable/stroke_drawable"do ImageView w pliku XML układu, a otrzymasz:

wprowadź opis zdjęcia tutaj

Nie jestem jednak pewien, jak dodać cień (który będzie działał na starszych wersjach Androida). Korzystając z FloatingActionButton (z zależności „com.google.android.material: material” ), nie udało mi się zmusić bitmapy do wypełnienia samego FAB. Używanie go zamiast tego może być jeszcze lepsze, jeśli zadziała.


EDYCJA: jeśli chcesz dodać cień elewacji (dostępny z API 21), możesz nieco zmienić to, co napisałem:

Wewnątrz pliku XML układu:

<androidx.appcompat.widget.AppCompatImageView android:padding="4dp"
    android:id="@+id/avatarImageView" android:layout_width="100dp" android:layout_height="100dp" android:elevation="8dp"
    android:layout_gravity="center" android:background="@drawable/stroke_drawable" tools:srcCompat="@drawable/avatar_1"/>

CircularShadowViewOutlineProvider.kt

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
class CircularShadowViewOutlineProvider : ViewOutlineProvider() {
    override fun getOutline(view: View, outline: Outline) {
        val size = Math.max(view.width, view.height)
        outline.setRoundRect(0, 0, size, size, size / 2f)
    }
}

W kodzie:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        avatarImageView.outlineProvider = CircularShadowViewOutlineProvider()

Wynik:

wprowadź opis zdjęcia tutaj

programista Androida
źródło
0

Mam proste rozwiązanie. Utwórz nowy zasób obrazu, klikając prawym przyciskiem myszy nazwę pakietu i wybierając Nowy-> zasób obrazu. Wprowadź nazwę (dowolną nazwę) i ścieżkę (lokalizację obrazu w systemie). Następnie kliknij przycisk Dalej i zakończ. Jeśli wprowadzisz nazwę obrazu jako „img”, okrągły folder o nazwie „img_round” zostanie utworzony automatycznie w folderze mipmap.

Następnie zrób to:

<ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@mipmap/img_round"/>

Podgląd może nadal wyświetlać prostokątny obraz. Ale jeśli uruchomisz aplikację na swoim urządzeniu, będzie ona okrągła.

Wisznu Priyaa
źródło
0

Utwórz CustomImageview, a następnie po prostu zastąp jego onDraw()następującą metodę:

@Override
protected void onDraw(Canvas canvas) {

    float radius = this.getHeight()/2;
    Path path = new Path();
    RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
    path.addRoundRect(rect, radius, radius, Path.Direction.CW);
    canvas.clipPath(path);
    super.onDraw(canvas);

}

Jeśli chcesz również kod niestandardowego widgetu:

CircularImageView.java

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

import androidx.annotation.Nullable;

public class CircularImageView extends ImageView {

    private Drawable image;

    public CircularImageView(Context context) {
        super(context);

        init(null, 0);
    }

    public CircularImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        init(attrs, 0);
    }

    public CircularImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init(attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        float radius = this.getHeight()/2;
        Path path = new Path();
        RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        path.addRoundRect(rect, radius, radius, Path.Direction.CW);
        canvas.clipPath(path);
        super.onDraw(canvas);

    }

    private void init(AttributeSet attrs, int defStyle) {
        TypedArray a = Utils.CONTEXT.getTheme().obtainStyledAttributes(attrs, R.styleable.CircularImageView, 0, 0);
        try {
            image = a.getDrawable(R.styleable.CircularImageView_src);
        } finally {
            a.recycle();
        }

        this.setImageDrawable(image);
    }
}

Dodaj również następujący kod do pliku res / attrs.xml, aby utworzyć wymagany atrybut: -

<declare-styleable name="CircularImageView">
        <attr name="src" format="reference" />
</declare-styleable>
Mahdi Astanei
źródło
Działa to, gdy widok obrazu nie ma tła. Co wtedy zrobić?
Supradip.M,
0
if you want to set edit icon on to circle imageview than put this below code.

 <FrameLayout
                android:layout_width="@dimen/_100sdp"
                android:layout_height="@dimen/_100sdp"
                android:layout_gravity="center"
                android:layout_marginTop="10dp">

                <de.hdodenhof.circleimageview.CircleImageView
                    android:id="@+id/profilePic"
                    android:layout_width="@dimen/_100sdp"
                    android:layout_height="@dimen/_100sdp"
                    android:layout_gravity="bottom|center_horizontal"
                    android:src="@drawable/ic_upload" />

                <de.hdodenhof.circleimageview.CircleImageView
                    android:id="@+id/iv_camera"
                    android:layout_width="@dimen/_30sdp"
                    android:layout_height="@dimen/_30sdp"
                    android:layout_gravity="top|right"
                    android:src="@drawable/edit"/>
            </FrameLayout>
MEGHA DOBARIYA
źródło
0

jeśli wolisz wyciąć obraz do wyświetlenia w kółku, proszę bardzo

public static Bitmap getCircularBitmap(Bitmap bitmap) {
        Bitmap output;

        if (bitmap.getWidth() > bitmap.getHeight()) {
            output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        } else {
            output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

        float r = 0;

        if (bitmap.getWidth() > bitmap.getHeight()) {
            r = bitmap.getHeight() / 2;
        } else {
            r = bitmap.getWidth() / 2;
        }

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawCircle(r, r, r, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }
Nasib
źródło
-1

wystarczy użyć tego prostego kodu: Najpierw dodaj zależność:

implementation 'de.hdodenhof:circleimageview:2.2.0'

następnie dodaj w układzie xml następujący kod: -

<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
                                        android:id="@+id/Imgshaligram"
                                        android:layout_width="96dp"
                                        android:layout_height="96dp"
                                        android:src="@drawable/shaligram"
                                        app:civ_border_color="#d1b1b1"

                                        android:foregroundGravity="center"/>
Pradeep Sheoran
źródło
-1

te dwie biblioteki mogą ci pomóc.

https://github.com/vinc3m1/RoundedImageView

zaimplementuj poniższy kod:

implementation 'com.makeramen:roundedimageview:2.3.0'

Proste użycie:

<com.makeramen.roundedimageview.RoundedImageView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/imageView1"
        android:src="@drawable/photo1"
        android:scaleType="fitCenter"
        app:riv_corner_radius="30dip"
        app:riv_border_width="2dip"
        app:riv_border_color="#333333"
        app:riv_mutate_background="true"
        app:riv_tile_mode="repeat"
        app:riv_oval="true" />

https://github.com/chirag-kachhadiya/RoundedImageView

Proste użycie:

zaimplementuj poniższy kod:

implementation 'com.github.chirag-kachhadiya:RoundedImageView:1.0'



 <com.infinityandroid.roundedimageview.RoundedImageView
                android:layout_width="150dp"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:adjustViewBounds="true"
                android:src="@drawable/the_hundred"
                app:corner_radius="10" />
Alirezaaraby
źródło
-1

Jak opisano w odpowiedzi Orhana Obuta, ale ze zmianami:

<ImageView
    android:layout_width="0dp"  //or use your own value
    android:layout_height="match_parent"
    android:src="@drawable/img"
    android:layout_weight="75" />// in case of use of weight

aby uniknąć rozciągnięcia obrazu. I img.xml:

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/profile" />
<item android:drawable="@drawable/circle" /></layer-list>

(bez zmian) i circle.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadiusRatio="2"
android:shape="ring"
android:thickness="300dp"
android:useLevel="false">
<solid android:color="@android:color/white"/>
<stroke
    android:width="2dp"
    android:color="@android:color/black"/>
</shape>
 

tutaj grubość pierścienia osiągnęła maksimum - 1000dp
i promień Współczynnik jest połową szerokości obrazu (maksymalna szerokość pierścienia, tak?) - 2,
a kreska jest w razie potrzeby wymaganą krawędzią.
Użyłem kwadratowego obrazu png (profile.png), btw. Z tą samą szerokością i wysokością. Jest to poprawne w przypadku dowolnych wymiarów ImageView. wprowadź opis zdjęcia tutaj

CodeToLife
źródło