Ich habe einen Custom ListView
, der eine ImageView
und eine TextView
enthält. Alles funktioniert gut.
Was ich möchte ist, dass das Bild in der Liste in der runden Ecke angezeigt wird. Vom Webservice bekomme ich die Bilder in Rechteckform. Aber ich möchte es in Round corner ImageView
wie unten anzeigen.
Kann mir jemand zeigen, wie ich das Bild in einer runden Ecke maskieren kann?
Ich habe bereits versucht, die zeichnende Datei wie unten beschrieben zu erstellen und als src in ImageView
anzuwenden. Aber nichts funktioniert für mich.
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<item>
<shape Android:shape="oval" >
<solid Android:color="#FFFFFF" />
<padding
Android:bottom="10dp"
Android:left="10dp"
Android:right="10dp"
Android:top="10dp" />
<corners Android:radius="5dp" />
</shape>
</item>
<item>
<shape Android:shape="oval" >
<padding
Android:bottom="5dp"
Android:left="5dp"
Android:right="5dp"
Android:top="5dp" />
<solid Android:color="#FFFFFF" />
</shape>
</item>
</layer-list>
BEARBEITET:
Bitte hilf mir.
Jede Hilfe wird geschätzt.
Vielen Dank
Ich habe folgende Lösung angewendet:
<FrameLayout
Android:id="@+id/imagemaskframe"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:padding="10dp" >
<ImageView
Android:id="@+id/op_ivpic"
Android:layout_width="80dp"
Android:layout_height="80dp"
Android:layout_gravity="center"
Android:scaleType="fitXY" />
<ImageView
Android:id="@+id/iv_mask_op"
Android:layout_width="80dp"
Android:layout_height="80dp"
Android:layout_gravity="center"
Android:adjustViewBounds="true"
Android:scaleType="fitXY"
Android:src="@drawable/imgmask" />
</FrameLayout>
Ich empfehle Ihnen eine andere Methode zu verwenden:
Eine FrameLayout
und zwei ImageView
können es tun.
<FrameLayout>
<ImageView /> your image
<ImageView /> put a image which has a transparent circle in it
</FrameLayout>
dann kann Ihr Bild über einen transparenten Kreis gesehen werden.
Am besten tun Sie dies in Canvas
mit PorterDuff
-Operationen und/oder Shaders
. Angenommen, Ihre Bitmap
ist verfügbar und in mBitmap
gespeichert.
Option 1: Shader verwenden.
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Load the bitmap as a shader to the Paint.
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
final Shader shader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint.setShader(shader);
// Draw a circle with the required radius.
final float halfWidth = canvas.getWidth()/2;
final float halfHeight = canvas.getHeight()/2;
final float radius = Math.max(halfWidth, halfHeight);
canvas.drawCircle(halfWidth, halfHeight, radius, Paint);
}
Option 2: Verwenden des PorterDuff-Modus.
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Create a circular path.
final float halfWidth = canvas.getWidth()/2;
final float halfHeight = canvas.getHeight()/2;
final float radius = Math.max(halfWidth, halfHeight);
final Path path = new Path();
path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawPath(path, Paint);
}
Hinweis:
Canvas
muss möglicherweise gespeichert und wiederhergestellt werden, wenn sie nicht durch eine Hardwaretextur gesichert ist. Die allgemeinen Ideen dazu werden hier nicht erwähnt.setWillNotDraw(false);
hinzuzufügen.Zusätzliche Referenzen:
Shaders
.Path
, um die Schaltfläche in Firefox für Android zu verwenden.Canvas
für das ICS vor dem ICS.Ich würde Picasso auf jeden Fall empfehlen, wie es andere tun. Dieses bisschen Code für eine meiner Aktivitätsklassen hat mir geholfen. Es verwendete eine Farbe, die ich in color.xml definiert hatte, und ein einfaches Layout (siehe unten).
ImageView profile_image = (ImageView) findViewById(R.id.profile_image);
mContext = profile_image.getContext();
// ----------------------------------------------------------------
// apply rounding to image
// see: https://github.com/vinc3m1/RoundedImageView
// ----------------------------------------------------------------
Transformation transformation = new RoundedTransformationBuilder()
.borderColor(getResources().getColor(R.color.my_special_orange))
.borderWidthDp(5)
.cornerRadiusDp(50)
.oval(false)
.build();
Picasso.with(mContext)
.load("http://{some_url}.jpg")
.fit()
.transform(transformation)
.into(profile_image);
Und die entsprechende Layoutdatei:
<LinearLayout
Android:orientation="horizontal"
Android:layout_width="fill_parent"
Android:layout_height="120dp"
Android:layout_alignParentTop="true"
Android:layout_alignParentStart="true"
Android:padding="12dp">
<ImageView
Android:id="@+id/profile_image"
Android:layout_width="80dp"
Android:layout_height="80dp"
Android:layout_gravity="center"/>
<LinearLayout
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="80dp"
Android:layout_gravity="center"
Android:padding="12dp">
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:textAppearance="?android:attr/textAppearanceLarge"
Android:text="First-Name"
Android:id="@+id/profile_first_name"
/>
<TextView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:textAppearance="?android:attr/textAppearanceSmall"
Android:text="Lastname"
Android:id="@+id/profile_last_name" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Hier ist das Ergebnis:
Eine RoundedBitmapDrawable
aus der v4 Support Library kann auf eine ImageView
angewendet werden, um den gewünschten Effekt zu erzielen:
ImageView imageView = (ImageView)findViewById(R.id.imageView);
Bitmap avatar = BitmapFactory.decodeResource(getResources(), R.drawable.avatar);
RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(getResources(), avatar);
roundDrawable.setCircular(true);
imageView.setImageDrawable(roundDrawable);
Eine einfache Lösung und ohne schwarzen Hintergrund !
public class CircleImageView extends ImageView
{
public CircleImageView(Context context)
{
super(context);
}
@Override
protected void onDraw(Canvas canvas)
{
// Create a circular path.
final float halfWidth = canvas.getWidth()/2;
final float halfHeight = canvas.getHeight()/2;
final float radius = Math.max(halfWidth, halfHeight);
final Path path = new Path();
path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);
canvas.clipPath(path);
super.onDraw(canvas);
}
}
Verweisen Sie auf den folgenden Code, der genau das tut, was Sie möchten.
https://github.com/vinc3m1/RoundedImageView
Wie Sie sagten, wenn Sie keine benutzerdefinierte Ansicht möchten, versuchen Sie die folgende Idee
erstellen Sie ein 9-Patch-Bild (z. B. einen Fotorahmen) mit abgerundeter Ecke und transparentem Hintergrund
erstellen Sie anschließend Relatives Layout/FrameLayout mit zwei Bildansichten wie folgt
<RelativeLayout ....>
<ImageView Android:id="@+id/myImage" ..>
<ImageView Android:id="@+id/myRoundCorner" Android:src="@drawable/myRoundCornerdFrame">
</RelativeLayout>
stellen Sie sicher, dass beide Bildansichten mit Ausnahme der Bildquelle dieselben Attribute aufweisen, und stellen Sie außerdem sicher, dass die Bildansicht, deren Quelle myRoundCornerFrame hat, über der anderen Bildansicht (oben) liegen sollte.
Probieren Sie einfach Android-Shape-Bildansicht - es sollte Ihnen helfen.
erstellen Sie eine XML-Datei mit dem Namen "roundimage.xml" im Zeichnungsordner "hdpi" und versuchen Sie den folgenden Code.
<?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/darker_gray" />
<corners Android:bottomRightRadius="50dip"
Android:bottomLeftRadius="50dip"
Android:topRightRadius="50dip"
Android:topLeftRadius="50dip"/>
</shape>
fügen Sie dann die Datei als Hintergrundbild in Ihren Bildhintergrund ein
Android:background="@drawable/roundimage"
Ich bitte Sie, die Maße und Farben entsprechend Ihren Anforderungen zu ändern.
bitte verwenden Sie diesen Code
package com.company.app.utils;
import Android.graphics.Bitmap;
import Android.graphics.Canvas;
import Android.graphics.Paint;
import Android.graphics.PorterDuffXfermode;
import Android.graphics.Rect;
import Android.graphics.RectF;
import Android.graphics.Bitmap.Config;
import Android.graphics.PorterDuff.Mode;
public class ImageHelper {
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), 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());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
Paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
Paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, Paint);
Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, Paint);
return output;
}
}
verwenden Sie dies, da dies funktioniert.
wenn Sie einen quadratischen Winkel wünschen, verwenden Sie diesen Befehl
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels ,
int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR)
{
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier = context.getResources().getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
//make sure that our rounded corner is scaled appropriately
final float roundPx = pixels*densityMultiplier;
Paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
Paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, Paint);
//draw rectangles over the corners we want to be square
if (squareTL ){
canvas.drawRect(0, 0, w/2, h/2, Paint);
}
if (squareTR ){
canvas.drawRect(w/2, 0, w, h/2, Paint);
}
if (squareBL ){
canvas.drawRect(0, h/2, w/2, h, Paint);
}
if (squareBR ){
canvas.drawRect(w/2, h/2, w, h, Paint);
}
Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(input, 0,0, Paint);
return output;
}
Außerdem habe ich ImageView überschrieben, um dies in xml zu definieren. Vielleicht möchten Sie etwas von der Logik hinzufügen, die der Super-Aufruf hier macht, aber ich habe es kommentiert, da es in meinem Fall nicht hilfreich ist.
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
Drawable drawable = getDrawable();
Bitmap b = ((BitmapDrawable)drawable).getBitmap() ;
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap=CropImageView.getRoundedCornerBitmap( getContext(),
bitmap,10, w, h , true, false,true, false);
canvas.drawBitmap(roundBitmap, 0,0 , null);
}
Um die Antwort von sriramramani (einschließlich des Fixes für schwarzen Hintergrund) zu erweitern, ist hier meine einfache ImageView-Version:
public class ExampleImageView extends ImageView {
public ExampleImageView(Context context) {
super(context);
init();
}
public ExampleImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ExampleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
void init() {
setWillNotDraw(false);
}
@Override
protected void onDraw(Canvas canvas) {
int count = canvas.saveLayer(0, 0, getWidth(), getHeight(), null,
Canvas.MATRIX_SAVE_FLAG |
Canvas.CLIP_SAVE_FLAG |
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG |
Canvas.FULL_COLOR_LAYER_SAVE_FLAG |
Canvas.CLIP_TO_LAYER_SAVE_FLAG);
super.onDraw(canvas);
// Create a circular path.
final float halfWidth = canvas.getWidth()/2;
final float halfHeight = canvas.getHeight()/2;
final float radius = Math.max(halfWidth, halfHeight);
final Path path = new Path();
path.addCircle(halfWidth, halfHeight, radius, Path.Direction.CCW);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawPath(path, Paint);
canvas.restoreToCount(count);
}
}
Eine Sache, wenn ich diese Zeile entferne:
setWillNotDraw(false);
Alles funktioniert noch. Nicht sicher, ob es benötigt wird?
hier, was ich getan habe ... aber mein bg img war rechteck.
ImageView ivLogo;
ivLogo=(ImageView)fragment.mRoot.findViewById(R.id.iv_offer_logo);
dann beim Einstellen des Bildes,
if(response.result.Partner.logo_url != null && !response.result.Partner.logo_url.equals("")){
ivLogo.setPadding(3,3,3,3);
DisplayImageOptions options =
WWFunctions.getDisplayImage(0);
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(mOfferDetailsFragment.getActivity() ));
imageLoader.displayImage(response.result.Partner.logo_url, ivLogo, options);
}
Für diejenigen, die Glide bereits verwenden, können Sie den Effekt mit RequestOptions erzielen:
RequestOptions requestOptions = new RequestOptions();
requestOptions = requestOptions.transforms(new CenterCrop(), new RoundedCorners(radiusInPixels));
Glide.with(context)
.load(imageUrl)
.apply(requestOptions)
.into(imageView);