0

我正在使用来自https://github.com/hdodenhof/CircleImageView的“Circleimageview”

试图设置边界资源,它没有帮助

这是我拥有的和想要的https://docs.google.com/document/d/1VqWmaFpooYtuk7dPUAh_5-rbEzcTQTW9Jvt8QX0TNT0/edit?usp=sharing

有任何想法吗?

4

1 回答 1

0

尝试这个 :

public class CircleImageView extends AppCompatImageView {

private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;

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

// Object used to draw
private Bitmap image;
private Drawable drawable;
private Paint paint;
private Paint paintBorder;

private Context context;

//region Constructor & Init Method
public CircleImageView(final Context context) {
    this(context, null);
}

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

public CircleImageView(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);
    this.context = context;

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

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

@Override
public ScaleType getScaleType() {
    return SCALE_TYPE;
}

@Override
public void setScaleType(ScaleType scaleType) {
    if (scaleType != SCALE_TYPE) {
        throw new IllegalArgumentException(String.format("ScaleType %s not supported. ScaleType.CENTER_CROP is used by default. So you don't need to use ScaleType.", 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 = canvas.getWidth();
        if (canvas.getHeight() < canvasSize) {
            canvasSize = 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;
    // Draw Border
    canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - (shadowRadius + shadowRadius / 2), paintBorder);
    // Draw CircularImageView
    canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - (shadowRadius + shadowRadius / 2), paint);
}

private void loadBitmap() {
    if (this.drawable == getDrawable())
        return;

    this.drawable = getDrawable();
    this.image = drawableToBitmap(this.drawable);
    updateShader();
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    canvasSize = w;
    if (h < canvasSize)
        canvasSize = h;
    if (image != null)
        updateShader();
}

private void drawShadow(float shadowRadius, int shadowColor) {
    this.shadowRadius = shadowRadius;
    this.shadowColor = shadowColor;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
        setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
    }
    paintBorder.setShadowLayer(shadowRadius, 0.0f, shadowRadius / 2, shadowColor);
}

private void updateShader() {
    if (image == null)
        return;

    // Crop Center Image
    image = cropBitmap(image);

    // Create Shader
    BitmapShader shader = new BitmapShader(image, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

    // Center Image in Shader
    Matrix matrix = new Matrix();
    matrix.setScale((float) canvasSize / (float) image.getWidth(), (float) canvasSize / (float) image.getHeight());
    shader.setLocalMatrix(matrix);

    // Set Shader in Paint
    paint.setShader(shader);
}

private Bitmap cropBitmap(Bitmap bitmap) {
    Bitmap bmp;
    if (bitmap.getWidth() >= bitmap.getHeight()) {
        bmp = Bitmap.createBitmap(
                bitmap,
                bitmap.getWidth() / 2 - bitmap.getHeight() / 2,
                0,
                bitmap.getHeight(), bitmap.getHeight());
    } else {
        bmp = Bitmap.createBitmap(
                bitmap,
                0,
                bitmap.getHeight() / 2 - bitmap.getWidth() / 2,
                bitmap.getWidth(), bitmap.getWidth());
    }
    return bmp;
}

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

    int intrinsicWidth = drawable.getIntrinsicWidth();
    int intrinsicHeight = drawable.getIntrinsicHeight();

    if (!(intrinsicWidth > 0 && intrinsicHeight > 0))
        return null;

    try {
        // Create Bitmap object out of the drawable
        Bitmap bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        return bitmap;
    } catch (OutOfMemoryError e) {
        // Simply return null of failed bitmap creations
        Log.e(getClass().toString(), "Encountered OutOfMemoryError while generating bitmap!");
        return null;
    }
}
//endregion

//region Mesure Method
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = measureWidth(widthMeasureSpec);
    int height = measureHeight(heightMeasureSpec);
    /*int imageSize = (width < height) ? width : height;
    setMeasuredDimension(imageSize, imageSize);*/
    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);
}


}

现在在 XML 文件中使用这个:

<com.xyz.customclass.CircleImageView
                android:id="@+id/img_event"
                android:layout_width="55dp"
                android:layout_height="55dp"
                app:civ_border="true"
                app:civ_border_color="@color/color_circular_home_image_border"
                app:civ_border_width="1dp"
                app:civ_shadow="true"
                app:civ_shadow_color="@color/color_circular_home_image_border"
                app:civ_shadow_radius="2"
                app:srcCompat="@mipmap/ocassion_placeholder" />

在 attr.xml 中添加这个(创建 attr.xml :在 res ->values->attr.xml 下)

<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_shadow" format="boolean"/>
    <attr name="civ_shadow_color" format="color"/>
    <attr name="civ_shadow_radius" format="float"/>
</declare-styleable>
于 2017-09-15T10:24:37.013 回答