Ich habe ein CircularImageView mit dieser Frage erstellt: Erstellen einer kreisförmigen Bildansicht in Android
Projekt herunterladen auf GitHub
1) Dies ist die CircularImageView-Klasse:
public class CircularImageView extends ImageView {
public CircularImageView(Context context) {
super(context);
}
public CircularImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircularImageView(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);
Bitmap roundBitmap = getCroppedBitmap(bitmap, getWidth());
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if(bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(), Bitmap.Config.ARGB_8888);
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
Paint paint = new Paint();
Paint.setAntiAlias(true);
Paint.setFilterBitmap(true);
Paint.setDither(true);
Paint.setColor(Color.parseColor("#BAB399"));
Canvas c = new Canvas(output);
c.drawARGB(0, 0, 0, 0);
c.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f, sbmp.getWidth() / 2+0.1f, Paint);
Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
c.drawBitmap(sbmp, rect, rect, Paint);
return output;
}
}
2) Ich verwende in meinem Layout so:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="#cccccc"
Android:gravity="center"
Android:orientation="vertical"
Android:padding="10dp" >
<com.mikhaellopez.circularimageview.CircularImageView
Android:id="@+id/imageViewCircular"
Android:layout_width="@dimen/image_view_size"
Android:layout_height="@dimen/image_view_size"
Android:layout_gravity="center"
Android:background="@drawable/border"
Android:src="@drawable/image" />
</LinearLayout>
3) Aktuelles Ergebnis im Bild:
Wie ändere ich diesen Code so, dass sich um meine Bildansicht ein Schatten und ein kreisförmiger Rand befindet?
Objektives Ergebnis:
Edit 15.10.2015:
Sie können meine GitHub-BibliothekCircularImageView mit allen Fixes verwenden oder herunterladen, indem Sie gradle Abhängigkeit verwenden:
compile 'com.mikhaellopez:circularimageview:2.0.1'
Ich habe das hier gefundene CircularImageView geändert , um das zu erreichen, was Sie wollen.
Um einen Schatten um die Grenze zu erzeugen, habe ich einfach diese beiden Linien verwendet:
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
Sie benötigen setLayerType
aufgrund der Hardwarebeschleunigung in HoneyComb und höher. Es funktionierte nicht ohne, als ich es ausprobierte.
Hier ist der vollständige Code:
import Android.annotation.SuppressLint;
import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapShader;
import Android.graphics.Canvas;
import Android.graphics.Color;
import Android.graphics.Paint;
import Android.graphics.Shader;
import Android.graphics.drawable.BitmapDrawable;
import Android.util.AttributeSet;
import Android.widget.ImageView;
public class CircularImageView extends ImageView
{
private int borderWidth = 4;
private int viewWidth;
private int viewHeight;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private BitmapShader shader;
public CircularImageView(Context context)
{
super(context);
setup();
}
public CircularImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
setup();
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setup();
}
private void setup()
{
// init Paint
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.BLACK);
}
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)
{
// load the bitmap
loadBitmap();
// init shader
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;
// 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
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)
{
// We were told how big to be
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)
{
// We were told how big to be
result = specSize;
}
else
{
// Measure the text (beware: ascent is a negative number)
result = viewHeight;
}
return (result + 2);
}
}
Ich hoffe, es hilft!
.
EDIT
Ich habe Ihr CircularImageView zusammengestellt und Unterstützung für Selector-Overlays hinzugefügt. Ich habe auch die Zeichenleistung deutlich verbessert ...
Um einen Rand hinzuzufügen, indem Sie ImageView
als Kreis erstellen, habe ich eine einfache Sache gemacht. Ich habe diese Klasse verwendet, um mein Bild als Kreis zu erstellen
package com.fidenz.fexceller.fexceller;
/**
* Created by Chathu Hettiarachchi on 5/18/2015.
*/
import Android.graphics.Bitmap;
import Android.graphics.BitmapShader;
import Android.graphics.Canvas;
import Android.graphics.ColorFilter;
import Android.graphics.Paint;
import Android.graphics.PixelFormat;
import Android.graphics.Rect;
import Android.graphics.RectF;
import Android.graphics.Shader;
import Android.graphics.drawable.Drawable;
public class RoundedImg extends Drawable {
private final Bitmap mBitmap;
private final Paint mPaint;
private final RectF mRectF;
private final int mBitmapWidth;
private final int mBitmapHeight;
public RoundedImg(Bitmap bitmap) {
mBitmap = bitmap;
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);
mBitmapWidth = mBitmap.getWidth();
mBitmapHeight = mBitmap.getHeight();
}
@Override
public void draw(Canvas canvas) {
canvas.drawOval(mRectF, mPaint);
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRectF.set(bounds);
}
@Override
public void setAlpha(int alpha) {
if (mPaint.getAlpha() != alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
}
@Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}
@Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}
public void setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
invalidateSelf();
}
@Override
public void setFilterBitmap(boolean filter) {
mPaint.setFilterBitmap(filter);
invalidateSelf();
}
@Override
public void setDither(boolean dither) {
mPaint.setDither(dither);
invalidateSelf();
}
public Bitmap getBitmap() {
return mBitmap;
}
}
und indem ich dies auf onCreate
verwende, habe ich das Bild zum Einstellen aufgerufen,
profilePic = (ImageView)findViewById(R.id.img_home_profile_pic);
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.no_image);
roundedImage = new RoundedImg(bm);
profilePic.setImageDrawable(roundedImage);
um einen Rand hinzuzufügen, erstellte ich eine XML-Kreisform wie folgt,
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="oval" >
<gradient Android:startColor="@color/ring_color" Android:endColor="@color/ring_color"
Android:angle="270"/>
</shape>
dann unter Verwendung von Layouts fügte ich eine RelativeLayout
mit ImageView
hinzu, indem Padding und Hintergrund mit wrap_content
gezeichnet werden und ich meine RelativeLayout
so einstellen
<RelativeLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:id="@+id/lay_rel_img"
Android:layout_gravity="center"
Android:padding="5dp"
Android:background="@drawable/circle">
<ImageView
Android:layout_width="150dp"
Android:layout_height="150dp"
Android:layout_gravity="center"
Android:id="@+id/img_home_profile_pic"
Android:src="@drawable/no_image"
Android:layout_centerHorizontal="true"/>
</RelativeLayout>
jetzt zeigt es so, ich weiß nicht, wie ich den Schatten hinzufügen soll, entschuldige mich auch dafür
canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, Paint);
Vor canvas.drawBitmap(roundBitmap, 0, 0, null);
c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2, Paint);
In c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2 - "the border with you prefer", Paint);
.Ich hoffe es hilft.
Vielleicht eine bessere Lösung hier .
Erstellen Sie ein benutzerdefiniertes Zeichenelement, und definieren Sie das Hintergrundattribut Ihrer ImageView. Sie können LayeredDrawable verwenden, um so viele verschiedene Komponenten für die Komponente zu erstellen, wie Sie möchten.
Wenn Sie diese Antwort auschecken, wird ein benutzerdefiniertes Rechteck erstellt (entspricht jedoch genau einem Oval\Circle): Wie erstellt man eine Google + Karten-Benutzeroberfläche in einer Listenansicht?
Ich habe eine Bibliothek gefunden, die genau das tut, was Sie möchten, und es funktionierte gut für mich ... __ Überprüfen Sie es heraus https://Android-arsenal.com/details/1/932
verwenden Sie einfach die drawCircle () -Methode mit mehr Breite und Höhe, bevor Sie das eigentliche Bild zeichnen. Erhöhen Sie die Breite und Höhe des neuen Methodenaufrufs nach Ihren Wünschen und legen Sie eine andere Farbe für Paint fest
Diese Klasse ist eine benutzerdefinierte kreisförmige Bildansicht mit Schatten, Strich und Sättigung. Mit dieser benutzerdefinierten kreisförmigen Bildansicht können Sie Ihr Bild in kreisförmiger Form mit Radius erstellen. Jungs für Circular Shadow ImageView Keine Notwendigkeit Github diese Klasse ist genug.
Hinzufügen von CircularImageView zu Ihrem Layout
// Bitmap myimage = BitmapFactory.decodeResource (getResources (), R.drawable.pic); CircularImageView c = new CircularImageView (diese Bildschirmbreite, Bildschirmhöhe, Bitmap-Bild); 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" />