CircledImageView 总是在圆形的前面有一个矩形的图片。

5

我能让CircledImageView正常工作,但是图片总是矩形的,并且在白色圆圈的前面(部分遮盖了圆圈)。这正确吗?我的假设是应该在圆圈内看到图片。

    <android.support.wearable.view.CircledImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/kids"
    app:circle_radius="60dp"
    app:circle_color="@color/white" />

xmlns:app="http://schemas.android.com/apk/res-auto"

感谢任何建议。

我已经阅读过这篇文章,但并没有帮助:Android Wear CircledImageView(和DelayedConfirmationView)始终是正方形

2个回答

2
我发现如果您使用固定的宽度/高度和app:circle_radius,则显示正确。
  <android.support.wearable.view.CircledImageView
        android:id="@+id/confirm"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="bottom|end"
        app:circle_color="@color/green"
        app:circle_radius="25dp" />

How it looks


-4

你可以创建自己的自定义圆形 ImageView,扩展 ImageView 类...

我已经创建了一个... 也许你可以使用它...

public class CircularImageView extends ImageView {
    private int borderWidth;
    private int canvasSize;
    private Bitmap image;
    private Paint paint;
    private Paint paintBorder;

    public CircularImageView(final Context context) {
        this(context, null);
    }

    public CircularImageView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.circularImageViewStyle);
    }

    public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // init paint
        paint = new Paint();
        paint.setAntiAlias(true);

        paintBorder = new Paint();
        paintBorder.setAntiAlias(true);

        // load the styled attributes and set their properties
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);

        if(attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
            int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
            setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
            setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
        }

        if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
            addShadow();

        attributes.recycle();
    }

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

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

    public void addShadow() {
        setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
        paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas) {
        // load the bitmap
        image = drawableToBitmap(getDrawable());

        // init shader
        if (image != null) {

            canvasSize = canvas.getWidth();
            if(canvas.getHeight()<canvasSize)
                canvasSize = canvas.getHeight();

            BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paint.setShader(shader);

            // 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 = (canvasSize - (borderWidth * 2)) / 2;
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
            canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
        }
    }

    @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 = 0;
        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 = 0;
        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);
    }

    public Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable == null) {
            return null;
        } else if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }

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

然后在 values/attrs 文件中添加以下行:

<declare-styleable name="CircularImageView">
        <attr name="border" format="boolean"></attr>
        <attr name="border_width" format="dimension"></attr>
        <attr name="border_color" format="color"></attr>
        <attr name="shadow" format="boolean"></attr>
    </declare-styleable>
    <declare-styleable name="Theme">
        <attr name="circularImageViewStyle" format="reference"></attr>
    </declare-styleable>

最后,你可以像这样定义这个圆形图片视图..
   <youpackage.name.CircularImageView
                xmlns:app="http://schemas.android.com/apk/res/yourpackage.name"
                android:id="@+id/imageView_Company_Logo"
                android:layout_width="65dp"
                android:layout_height="65dp"
                app:border="true"
                app:border_color="@color/App_Theme_Green"
                app:border_width="4dp"
                app:shadow="false"
                android:src="@drawable/ic_launcher" />
  1. 您可以通过在 app:border="true" 中设置 true/false 来应用/删除边框,并使用以下方式更改边框颜色和宽度

    app:border_color="@color/App_Theme_Green" app:border_width="4dp"

  2. 您可以通过在 app:border="true" 中设置 true/false 来应用/删除阴影

希望对您有所帮助..!!!


谢谢!那么CircledImageView是坏了,所以你们自己创建了一个吗? - Lim Thye Chean
我并没有真正尝试过CircledImageView.. 我发现我的自定义视图更有用且易于实现。 - iMDroid
2
你正在onDraw中分配一个Bitmap,这肯定对性能不利。此外,我建议使用内置的Bitmap而不是花费时间构建自己的Bitmap,这样你将拥有“最新”的版本,无论Google何时/是否决定在以后更新它。 - zoltish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接