J'ai un Custom ListView
qui contient une ImageView
et une TextView
. Tout fonctionne bien.
Ce que je veux, c'est que l'image affichée dans la liste soit en coin arrondi. Depuis le Webservice, les images sont en forme de rectangle. Mais je veux l'afficher dans Round corner ImageView
comme ci-dessous.
Quelqu'un peut-il me montrer comment je peux masquer l'image dans un coin arrondi?
J'ai déjà essayé en créant le fichier extractible comme ci-dessous et en l'appliquant comme src dans ImageView
. Mais rien ne fonctionne pour moi.
<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>
Édité:
Aidez-moi, s'il vous plaît.
Toute aide serait appréciée.
Merci
J'ai appliqué la solution ci-dessous:
<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>
Je vous suggère d'utiliser une autre méthode:
Une FrameLayout
et deux ImageView
peuvent le faire.
<FrameLayout>
<ImageView /> your image
<ImageView /> put a image which has a transparent circle in it
</FrameLayout>
votre image peut alors être vue via un cercle transparent.
Le meilleur moyen est de le faire dans Canvas
en utilisant PorterDuff
opérations et/ou Shaders
. Supposons que votre Bitmap
soit disponible et stockée dans mBitmap
.
Option 1: Utilisation de Shaders.
@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: Utiliser le mode PorterDuff.
@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);
}
Remarque:
Canvas
devra peut-être être sauvegardé et restauré s'il n'est pas sauvegardé par une texture matérielle. Les idées générales autour de cela ne sont pas mentionnées ici.setWillNotDraw(false);
au constructeur.Références supplémentaires:
Shaders
.Path
pour incurver le bouton dans Firefox pour Android.Canvas
, les cas de restauration et les cas spéciaux pour pré-ICS.Je recommanderais certainement Picasso, comme d’autres. Ce morceau de code pour l'une de mes classes d'activité a fait l'affaire pour moi. Il utilisait une couleur que j'avais définie dans color.xml et une présentation simple (voir ci-dessous).
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);
Et le fichier de mise en page correspondant:
<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>
Voici le résultat:
A RoundedBitmapDrawable
from de la bibliothèque de support v4 peut être appliqué à ImageView
pour obtenir l'effet souhaité:
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);
Une solution simple et sans fond noir !
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);
}
}
Reportez-vous au code suivant, qui fait exactement ce que vous voulez.
https://github.com/vinc3m1/RoundedImageView
Comme vous l'avez dit, si vous ne voulez pas de vue personnalisée, essayez alors l'idée suivante
créer une image .png de 9 correctifs (comme un cadre photo) avec un coin arrondi et un arrière-plan transparent
puis créez une disposition relative/FrameLayout avec deux vues d'image comme suit
<RelativeLayout ....>
<ImageView Android:id="@+id/myImage" ..>
<ImageView Android:id="@+id/myRoundCorner" Android:src="@drawable/myRoundCornerdFrame">
</RelativeLayout>
assurez-vous que les deux vues d'image ont les mêmes attributs, à l'exception de la source d'image, et assurez-vous également que la vue d'image qui a la source comme source myRoundCornerFrame doit être au-dessus (en haut) de la vue d'affichage.
Il suffit d’essayer Android-shape-imageview - cela devrait vous aider.
créez un fichier xml avec le nom roundimage.xml dans le dossier drawable hdpi et essayez le code suivant.
<?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>
puis incluez le fichier dans le fond de votre image en tant que
Android:background="@drawable/roundimage"
Je vous demande de changer les dimensions et les couleurs selon vos besoins.
veuillez utiliser ce 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;
}
}
utilisez ceci comme cela fonctionne.
si vous voulez un coin carré, utilisez ce
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;
}
De plus, j'ai écrasé ImageView pour l'inclure afin de pouvoir le définir au format XML. Vous voudrez peut-être ajouter une partie de la logique que le super appel fait ici, mais je l’ai commentée car elle n’est pas utile dans mon cas.
@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);
}
En développant la réponse de sriramramani (y compris le correctif pour fond noir), voici mon simple ImageView dans son intégralité:
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);
}
}
Une chose si je supprime cette ligne:
setWillNotDraw(false);
Tout fonctionne toujours. Vous ne savez pas si c'est nécessaire?
voici ce que j'ai fait .. mais mon bg img était rectangle.
ImageView ivLogo;
ivLogo=(ImageView)fragment.mRoot.findViewById(R.id.iv_offer_logo);
puis en fixant l'image,
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);
}
Pour ceux qui utilisent déjà Glide, vous pouvez obtenir l'effet avec RequestOptions :
RequestOptions requestOptions = new RequestOptions();
requestOptions = requestOptions.transforms(new CenterCrop(), new RoundedCorners(radiusInPixels));
Glide.with(context)
.load(imageUrl)
.apply(requestOptions)
.into(imageView);