xamarin.Android ImageView 图片圆角(自定义属性、扩展控件)
新增 /values/Attrs.xml 文件
<?xml version="1.0" encoding="utf-8" ?> <resources> <declare-styleable name="RoundImageView"> <attr name="border_width" format="dimension" /> <attr name="border_color" format="color" /> </declare-styleable> </resources>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.Graphics; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using Android.Util; using Java.Util.Jar; using Android.Graphics.Drawables; using static Android.Graphics.PorterDuff; using Android.Content.Res; namespace Dorid.UI { /// <summary> /// 圆角 /// </summary> public class RoundImageView: ImageView { private int mBorderWidth = 10; private Bitmap mask; private Paint paint; private Color mBorderColor = Color.ParseColor("#FFFFFF"); private Context mContext; public RoundImageView(Context context):base(context) { mContext = context; } public RoundImageView(Context context, IAttributeSet attrs) : base(context, attrs) { mContext = context; GetAttributes(context, attrs); } public RoundImageView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle) { mContext = context; GetAttributes(context, attrs); } /// <summary> /// 获取自定义属性 /// </summary> /// <param name="context"></param> /// <param name="attrs"></param> private void GetAttributes(Context context, IAttributeSet attrs) { TypedArray t_attrs = context.ObtainStyledAttributes(attrs, Resource.Styleable.RoundImageView); mBorderColor = t_attrs.GetColor(Resource.Styleable.RoundImageView_border_color, mBorderColor); int defalut = (int)(2 * context.Resources.DisplayMetrics.Density + 0.5f); mBorderWidth = t_attrs.GetDimensionPixelOffset(Resource.Styleable.RoundImageView_border_width, defalut); t_attrs.Recycle(); } protected override void OnDraw(Canvas canvas) { Drawable localDrawable = Drawable; if (localDrawable == null) return; if (localDrawable is NinePatchDrawable) return; if (this.paint == null) { PorterDuff.Mode localMode = PorterDuff.Mode.DstIn; Paint localPaint = new Paint(); localPaint.FilterBitmap = false; localPaint.AntiAlias = true; localPaint.SetXfermode(new PorterDuffXfermode(localMode)); this.paint = localPaint; } int width = Width; int height = Height; /** 保存layer */ int layer = canvas.SaveLayer(0.0F, 0.0F, width, height, null, SaveFlags.All); /** 设置drawable的大小 */ localDrawable.SetBounds(0, 0, width, height); /** 将drawable绑定到bitmap(this.mask)上面(drawable只能通过bitmap显示出来) */ localDrawable.Draw(canvas); if ((this.mask == null) || (this.mask.IsRecycled)) { this.mask = CreateOvalBitmap(width, height); } /** 将bitmap画到canvas上面 */ canvas.DrawBitmap(this.mask, 0.0F, 0.0F, this.paint); /** 将画布复制到layer上 */ canvas.RestoreToCount(layer); DrawBorder(canvas, width, height); } private void DrawBorder(Canvas canvas, int width, int height) { if (mBorderWidth == 0) return; Paint mBorderPaint = new Paint(); mBorderPaint.SetStyle(Paint.Style.Stroke); mBorderPaint.AntiAlias = true; mBorderPaint.Color= mBorderColor; mBorderPaint.StrokeWidth = mBorderWidth; /** * 坐标x:view宽度的一般 坐标y:view高度的一般 半径r:因为是view的宽度-border的一半 */ canvas.DrawCircle(width >> 1, height >> 1, (width - mBorderWidth) >> 1, mBorderPaint); canvas = null; } /// <summary> /// 获取一个bitmap,目的是用来承载drawable; /// 将这个bitmap放在canvas上面承载,并在其上面画一个椭圆(其实也是一个圆,因为width=height)来固定显示区域 /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public Bitmap CreateOvalBitmap(int width, int height) { Bitmap.Config localConfig = Bitmap.Config.Argb8888; Bitmap localBitmap = Bitmap.CreateBitmap(width, height, localConfig); Canvas localCanvas = new Canvas(localBitmap); Paint localPaint = new Paint(); int padding = mBorderWidth - 3; /** * 设置椭圆的大小(因为椭圆的最外边会和border的最外边重合的,如果图片最外边的颜色很深,有看出有棱边的效果,所以为了让体验更加好, * 让其缩进padding px) */ RectF localRectF = new RectF(padding, padding, width - padding, height - padding); localCanvas.DrawOval(localRectF, localPaint); return localBitmap; } } }
axml 使用
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:controls="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:minWidth="25px" android:minHeight="25px" android:background="@color/activity_bg_color"> <Dorid.UI.RoundImageView android:src="@drawable/icon" android:layout_height="40dp" android:layout_alignParentRight="true" controls:border_width="3dp" controls:border_color="#CCCCCC" android:id="@+id/iv_userphoto_mycenter_myprofile" android:layout_width="40dp" android:layout_marginRight="20dp" /> </LinearLayout>