首页 文章

ImageView循环通过xml

提问于
浏览
141

我想把我的 ImageView 中的任何图像变成带边框的圆形图像 .

我搜索但找不到任何有用的信息(我试过的任何东西都不起作用) .

我怎样才能通过xml实现这一点:用某个src创建一个 ImageView 并使其带边框?

17 回答

  • -1

    您可以制作一个带有白色边框和透明内容的简单圆圈 .

    // 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>
    

    然后创建一个可绘制的图层列表,并将其作为背景添加到您的图像视图中 .

    // 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/ic_launcher"/>
        <item android:drawable="@drawable/circle"/>
    
    </layer-list>
    

    并将其作为您的imageview的背景 .

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

    你会有类似的东西 .

    enter image description here

  • 216

    这是我设计的最简单的方法 . 试试这个 .

    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>
    

    如果您正在使用lollipop以上的Android版本

    <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>
    
  • 5

    我希望这对你有所帮助 .

    1) With Third-party Library

    enter image description here

    <de.hdodenhof.circleimageview.CircleImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/profile_image"
            android:layout_width="120dp"
            android:layout_height="120dp"
            android:layout_centerInParent="true"
            android:src="@drawable/your_picture"
            app:civ_border_color="@color/colorAccent"
            app:civ_border_width="3dp" />
    

    Note : In your project, open your_app > Gradle Scripts > build.gradle (Module: app) and add the following implementation statement to the dependencies{}

    implementation 'de.hdodenhof:circleimageview:2.2.0'
    

    有关完整说明,请查看:The Source here.

    2) Without Third-party Library

    package com.mypackage.custom;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Bitmap;
    import android.graphics.BitmapShader;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.ColorFilter;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Shader;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.support.v7.widget.AppCompatImageView;
    import android.util.AttributeSet;
    
    import com.mypackage.R;
    
    import static android.widget.ImageView.ScaleType.CENTER_CROP;
    import static android.widget.ImageView.ScaleType.CENTER_INSIDE;
    
    
    public class CircularImageView extends AppCompatImageView {
    
        // Default Values
        private static final float DEFAULT_BORDER_WIDTH = 4;
        private static final float DEFAULT_SHADOW_RADIUS = 8.0f;
    
        // Properties
        private float borderWidth;
        private int canvasSize;
        private float shadowRadius;
        private int shadowColor = Color.BLACK;
        private ShadowGravity shadowGravity = ShadowGravity.BOTTOM;
        private ColorFilter colorFilter;
    
        // Object used to draw
        private Bitmap image;
        private Drawable drawable;
        private Paint paint;
        private Paint paintBorder;
        private Paint paintBackground;
    
        //region Constructor & Init Method
        public CircularImageView(final Context context) {
            this(context, null);
        }
    
        public CircularImageView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CircularImageView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context, attrs, defStyleAttr);
        }
    
        private void init(Context context, AttributeSet attrs, int defStyleAttr) {
            // Init paint
            paint = new Paint();
            paint.setAntiAlias(true);
    
            paintBorder = new Paint();
            paintBorder.setAntiAlias(true);
    
            paintBackground = new Paint();
            paintBackground.setAntiAlias(true);
    
            // Load the styled attributes and set their properties
            TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyleAttr, 0);
    
            // Init Border
            if (attributes.getBoolean(R.styleable.CircularImageView_civ_border, true)) {
                float defaultBorderSize = DEFAULT_BORDER_WIDTH * getContext().getResources().getDisplayMetrics().density;
                setBorderWidth(attributes.getDimension(R.styleable.CircularImageView_civ_border_width, defaultBorderSize));
                setBorderColor(attributes.getColor(R.styleable.CircularImageView_civ_border_color, Color.WHITE));
            }
    
            setBackgroundColor(attributes.getColor(R.styleable.CircularImageView_civ_background_color, Color.WHITE));
    
            // Init Shadow
            if (attributes.getBoolean(R.styleable.CircularImageView_civ_shadow, false)) {
                shadowRadius = DEFAULT_SHADOW_RADIUS;
                drawShadow(attributes.getFloat(R.styleable.CircularImageView_civ_shadow_radius, shadowRadius),
                        attributes.getColor(R.styleable.CircularImageView_civ_shadow_color, shadowColor));
                int shadowGravityIntValue = attributes.getInteger(R.styleable.CircularImageView_civ_shadow_gravity, ShadowGravity.BOTTOM.getValue());
                shadowGravity = ShadowGravity.fromValue(shadowGravityIntValue);
            }
    
            attributes.recycle();
        }
        //endregion
    
        //region Set Attr Method
        public void setBorderWidth(float borderWidth) {
            this.borderWidth = borderWidth;
            requestLayout();
            invalidate();
        }
    
        public void setBorderColor(int borderColor) {
            if (paintBorder != null)
                paintBorder.setColor(borderColor);
            invalidate();
        }
    
        public void setBackgroundColor(int backgroundColor) {
            if (paintBackground != null)
                paintBackground.setColor(backgroundColor);
            invalidate();
        }
    
        public void addShadow() {
            if (shadowRadius == 0)
                shadowRadius = DEFAULT_SHADOW_RADIUS;
            drawShadow(shadowRadius, shadowColor);
            invalidate();
        }
    
        public void setShadowRadius(float shadowRadius) {
            drawShadow(shadowRadius, shadowColor);
            invalidate();
        }
    
        public void setShadowColor(int shadowColor) {
            drawShadow(shadowRadius, shadowColor);
            invalidate();
        }
    
        public void setShadowGravity(ShadowGravity shadowGravity) {
            this.shadowGravity = shadowGravity;
            invalidate();
        }
    
        @Override
        public void setColorFilter(ColorFilter colorFilter) {
            if (this.colorFilter == colorFilter)
                return;
            this.colorFilter = colorFilter;
            drawable = null; // To force re-update shader
            invalidate();
        }
    
        @Override
        public ScaleType getScaleType() {
            ScaleType currentScaleType = super.getScaleType();
            return currentScaleType == null || currentScaleType != CENTER_INSIDE ? CENTER_CROP : currentScaleType;
        }
    
        @Override
        public void setScaleType(ScaleType scaleType) {
            if (scaleType != CENTER_CROP && scaleType != CENTER_INSIDE) {
                throw new IllegalArgumentException(String.format("ScaleType %s not supported. " +
                        "Just ScaleType.CENTER_CROP & ScaleType.CENTER_INSIDE are available for this library.", scaleType));
            } else {
                super.setScaleType(scaleType);
            }
        }
        //endregion
    
        //region Draw Method
        @Override
        public void onDraw(Canvas canvas) {
            // Load the bitmap
            loadBitmap();
    
            // Check if image isn't null
            if (image == null)
                return;
    
            if (!isInEditMode()) {
                canvasSize = Math.min(canvas.getWidth(), canvas.getHeight());
            }
    
            // circleCenter is the x or y of the view's center
            // radius is the radius in pixels of the cirle to be drawn
            // paint contains the shader that will texture the shape
            int circleCenter = (int) (canvasSize - (borderWidth * 2)) / 2;
            float margeWithShadowRadius = shadowRadius * 2;
    
            // Draw Border
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - margeWithShadowRadius, paintBorder);
            // Draw Circle background
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - margeWithShadowRadius, paintBackground);
            // Draw CircularImageView
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - margeWithShadowRadius, paint);
        }
    
        private void loadBitmap() {
            if (drawable == getDrawable())
                return;
    
            drawable = getDrawable();
            image = drawableToBitmap(drawable);
            updateShader();
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            canvasSize = Math.min(w, h);
            if (image != null)
                updateShader();
        }
    
        private void drawShadow(float shadowRadius, int shadowColor) {
            this.shadowRadius = shadowRadius;
            this.shadowColor = shadowColor;
            setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
    
            float dx = 0.0f;
            float dy = 0.0f;
    
            switch (shadowGravity) {
                case CENTER:
                    dx = 0.0f;
                    dy = 0.0f;
                    break;
                case TOP:
                    dx = 0.0f;
                    dy = -shadowRadius / 2;
                    break;
                case BOTTOM:
                    dx = 0.0f;
                    dy = shadowRadius / 2;
                    break;
                case START:
                    dx = -shadowRadius / 2;
                    dy = 0.0f;
                    break;
                case END:
                    dx = shadowRadius / 2;
                    dy = 0.0f;
                    break;
            }
    
            paintBorder.setShadowLayer(shadowRadius, dx, dy, shadowColor);
        }
    
        private void updateShader() {
            if (image == null)
                return;
    
            // Create Shader
            BitmapShader shader = new BitmapShader(image, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
    
            // Center Image in Shader
            float scale = 0;
            float dx = 0;
            float dy = 0;
    
            switch (getScaleType()) {
                case CENTER_CROP:
                    if (image.getWidth() * getHeight() > getWidth() * image.getHeight()) {
                        scale = getHeight() / (float) image.getHeight();
                        dx = (getWidth() - image.getWidth() * scale) * 0.5f;
                    } else {
                        scale = getWidth() / (float) image.getWidth();
                        dy = (getHeight() - image.getHeight() * scale) * 0.5f;
                    }
                    break;
                case CENTER_INSIDE:
                    if (image.getWidth() * getHeight() < getWidth() * image.getHeight()) {
                        scale = getHeight() / (float) image.getHeight();
                        dx = (getWidth() - image.getWidth() * scale) * 0.5f;
                    } else {
                        scale = getWidth() / (float) image.getWidth();
                        dy = (getHeight() - image.getHeight() * scale) * 0.5f;
                    }
                    break;
            }
    
            Matrix matrix = new Matrix();
            matrix.setScale(scale, scale);
            matrix.postTranslate(dx, dy);
            shader.setLocalMatrix(matrix);
    
            // Set Shader in Paint
            paint.setShader(shader);
    
            // Apply colorFilter
            paint.setColorFilter(colorFilter);
        }
    
        private Bitmap drawableToBitmap(Drawable drawable) {
            if (drawable == null) {
                return null;
            } else if (drawable instanceof BitmapDrawable) {
                return ((BitmapDrawable) drawable).getBitmap();
            }
    
            try {
                // Create Bitmap object out of the drawable
                Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
                Canvas canvas = new Canvas(bitmap);
                drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                drawable.draw(canvas);
                return bitmap;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        //endregion
    
        //region Measure Method
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int width = measureWidth(widthMeasureSpec);
            int height = measureHeight(heightMeasureSpec);
            setMeasuredDimension(width, height);
        }
    
        private int measureWidth(int measureSpec) {
            int result;
            int specMode = MeasureSpec.getMode(measureSpec);
            int specSize = MeasureSpec.getSize(measureSpec);
    
            if (specMode == MeasureSpec.EXACTLY) {
                // The parent has determined an exact size for the child.
                result = specSize;
            } else if (specMode == MeasureSpec.AT_MOST) {
                // The child can be as large as it wants up to the specified size.
                result = specSize;
            } else {
                // The parent has not imposed any constraint on the child.
                result = canvasSize;
            }
    
            return result;
        }
    
        private int measureHeight(int measureSpecHeight) {
            int result;
            int specMode = MeasureSpec.getMode(measureSpecHeight);
            int specSize = MeasureSpec.getSize(measureSpecHeight);
    
            if (specMode == MeasureSpec.EXACTLY) {
                // We were told how big to be
                result = specSize;
            } else if (specMode == MeasureSpec.AT_MOST) {
                // The child can be as large as it wants up to the specified size.
                result = specSize;
            } else {
                // Measure the text (beware: ascent is a negative number)
                result = canvasSize;
            }
    
            return result + 2;
        }
        //endregion
    
        public enum ShadowGravity {
            CENTER,
            TOP,
            BOTTOM,
            START,
            END;
    
            public int getValue() {
                switch (this) {
                    case CENTER:
                        return 1;
                    case TOP:
                        return 2;
                    case BOTTOM:
                        return 3;
                    case START:
                        return 4;
                    case END:
                        return 5;
                }
                throw new IllegalArgumentException("Not value available for this ShadowGravity: " + this);
            }
    
            public static ShadowGravity fromValue(int value) {
                switch (value) {
                    case 1:
                        return CENTER;
                    case 2:
                        return TOP;
                    case 3:
                        return BOTTOM;
                    case 4:
                        return START;
                    case 5:
                        return END;
                }
                throw new IllegalArgumentException("This value is not supported for ShadowGravity: " + value);
            }
    
        }
    }
    

    res/values/attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="CircularImageView">
            <attr name="civ_border" format="boolean" />
            <attr name="civ_border_width" format="dimension" />
            <attr name="civ_border_color" format="color" />
            <attr name="civ_background_color" format="color" />
            <attr name="civ_shadow" format="boolean" />
            <attr name="civ_shadow_color" format="color" />
            <attr name="civ_shadow_radius" format="float" />
            <attr name="civ_shadow_gravity">
                <flag name="center" value="1" />
                <flag name="top" value="2" />
                <flag name="bottom" value="3" />
                <flag name="start" value="4" />
                <flag name="end" value="5" />
            </attr>
        </declare-styleable>
    </resources>
    

    Layout

    <com.mypackage.CircularImageView
            android:id="@+id/iv_profile"
            android:layout_width="120dp"
            android:layout_height="120dp"
            android:layout_centerInParent="true"
            android:src="@drawable/your_picture"
            app:civ_border="true"
            app:civ_border_color="@color/colorAccent"
            app:civ_border_width="3dp"/>
    
  • -1

    以上方法使用 src 属性 . 我做的是将两个图像视图放在一个框架布局内,一个在另一个上面,如下所示:

    <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>
    

    只需将circular_crop.png放在您的可绘制文件夹中,该文件夹的形状为图像尺寸(在我的情况下为正方形),中间有白色背景和透明圆圈 . 如果您需要方形图像视图,可以使用此图像 .

    只需下载上面的图片 .

  • 0

    以下是最简单的方法之一,使用以下代码:

    Dependencies

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

    XML Code

    <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
    

    Screenshot:

    Screenshot

    资料来源:Circular ImageView GitHub Repository

    enter image description here

  • 80

    glide库和RoundedBitmapDrawableFactory类的帮助下,它很容易实现 . 您可能需要创建圆形占位符图像 .

    滑翔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);
                }
            });
    
  • 27

    这样就可以了:

    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(图层列表)

    <?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>
    

    你的布局

    <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"/>
    
  • 1

    我使用shape = "oval"而不是下面的"ring" . 它对我有用 . 为了使图像保持在边界内,我使用 <padding> 并在 <ImageView> 中将 <adjustViewBounds> 设置为true . 我尝试过尺寸在50 x 50像素到200x200像素之间的图像 .

  • 5

    只需使用这些代码行即可完成:

    <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" />
    

    enter image description here

    别忘了导入:

    import de.hdodenhof.circleimageview.CircleImageView;
    

    在build.gradle中添加此库:

    compile 'de.hdodenhof:circleimageview:2.1.0'
    
  • -1

    创建一个CustomImageview,它的 onDraw() 方法如下:

    @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);
    
    }
    
  • 1

    此类是具有阴影,笔触,饱和度的自定义圆形图像视图,使用此自定义圆形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" />
    
  • 183

    @Jyotman Singh,答案非常好(对于纯色背景),所以我想通过共享矢量drawable来增强它,可以根据您的需要重新着色,也很方便,因为矢量单件形状可以很好地扩展 .

    这是矩形圆形(@ 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>
    

    用法是一样的:

    <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>
    
  • 17

    实际上,您可以使用Google通过支持库RoundedBitmapDrawableFactory类(herehere)提供的内容,而不是使用第三方库:

    摇篮:

    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>
    

    结果:

    enter image description here

    并且,假设您想在其上添加边框,您可以使用此示例:

    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>
    

    并将 android:foreground="@drawable/stroke_drawable" 添加到布局XML文件中的ImageView,你得到这个:

    enter image description here

    我不知道如何添加阴影(这将适用于较旧的Android版本) . 使用FloatingActionButton(来自"com.google.android.material:material" dependency),我无法使位图填充FAB本身 . 如果有效的话,使用它可能会更好 .


    编辑:如果你想添加高程阴影(可从API 21获得),你可以改变我写的内容:

    Inside the layout XML file:

    <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)
        }
    }
    

    In code:

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

    结果:

    enter image description here

  • 0

    只需使用这个简单的代码:首先添加依赖:

    implementation 'de.hdodenhof:circleimageview:2.2.0'
    

    然后在xml布局中添加以下代码: -

    <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"/>
    
  • 0

    使用下面的代码,你可以修改它:

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.PorterDuff.Mode;
    import android.graphics.PorterDuffXfermode;
    import android.graphics.Rect;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.widget.ImageView;
    
    public class RoundedImageView extends ImageView {
    
        public RoundedImageView(Context context) {
            super(context);
        }
    
        public RoundedImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
    
            Drawable drawable = getDrawable();
    
            if (drawable == null) {
                return;
            }
    
            if (getWidth() == 0 || getHeight() == 0) {
                return;
            }
            Bitmap b = ((BitmapDrawable) drawable).getBitmap();
            Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
    
            int w = getWidth();
            @SuppressWarnings("unused")
            int h = getHeight();
    
            Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
            canvas.drawBitmap(roundBitmap, 0, 0, null);
    
        }
    
        public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
            Bitmap sbmp;
    
            if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
                float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
                float factor = smallest / radius;
                sbmp = Bitmap.createScaledBitmap(bmp,
                        (int) (bmp.getWidth() / factor),
                        (int) (bmp.getHeight() / factor), false);
            } else {
                sbmp = bmp;
            }
    
            Bitmap output = Bitmap.createBitmap(radius, radius, Config.ARGB_8888);
            Canvas canvas = new Canvas(output);
    
            final String color = "#BAB399";
            final Paint paint = new Paint();
            final Rect rect = new Rect(0, 0, radius, radius);
    
            paint.setAntiAlias(true);
            paint.setFilterBitmap(true);
            paint.setDither(true);
            canvas.drawARGB(0, 0, 0, 0);
            paint.setColor(Color.parseColor(color));
            canvas.drawCircle(radius / 2 + 0.7f, radius / 2 + 0.7f,
                    radius / 2 + 0.1f, paint);
            paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
            canvas.drawBitmap(sbmp, rect, rect, paint);
    
            return output;
        }
    
    }
    
  • 15

    试试这个 .

    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);
         }
     }
    

    并在布局中使用此ImageView,如:

    <com.app.Demo.RoundedImageView
         android:id="@+id/iv_profileImage"
         android:layout_width="70dp"
         android:layout_height="70dp"
         android:layout_centerHorizontal="true"
        />
    
  • 0

    正如Orhan Obut的回答所述,但随着变化:

    <ImageView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:src="@drawable/img"
        android:layout_weight="75" />
    

    避免图像的延伸 . 和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>
    

    (没有更改)和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>
    

    这里环的厚度最大 - 1000dp
    和radiusRatio是图像宽度的一半(最大环宽,是吗?) - 2
    如果需要,笔划是必需的边框 .
    我使用了square png image(profile.png),顺便说一句 . 具有相同的宽度和高度 . 对于任意ImageView维度,这是正确的 .
    enter image description here

相关问题