using System; using Android.Content; using Android.Graphics; using Android.Graphics.Drawables; using Android.OS; using Android.Util; using Android.Views; namespace Shared { //已经全面检查了代码 /// /// Button 按键 /// public class ImageView : View { /// /// 当前视图 /// /// The android button. AndroidImageView currentButton { get { return AndroidView as AndroidImageView; } set { AndroidView = value; } } /// /// 构造函数 /// public ImageView() { currentButton = new AndroidImageView(Application.Activity, this); } internal string imagePath, tempImagePath; /// /// 非选中状态的背景图路径 /// /// The un selected image path. public string ImagePath { get { return imagePath; } set { tempImagePath = value; if (!IsCanRefresh) { return; } if (imageBytes != null) { (AndroidView as AndroidImageView).SetImageDrawable(Bytes2Drawable(imageBytes)); return; } if (ImagePath == value) { return; } imagePath = value; Background(value); } } byte[] imageBytes; public byte[] ImageBytes { get { return imageBytes; } set { imageBytes = value; ImagePath = tempImagePath; } } public override uint Radius { get { return base.Radius; } set { base.Radius = value; if (!IsCanRefresh && Radius == value) { return; } currentButton.Invalidate(); } } public override void Refresh() { base.Refresh(); ImagePath = tempImagePath; } } public class AndroidImageView : Android.Widget.ImageView { public override bool OnTouchEvent(MotionEvent e) { base.OnTouchEvent(e); if (view != null) { view.TouchEvent(e); } return true; } /** * 图片的类型,圆形or圆角 */ private int type = TYPE_ROUND; public static int TYPE_CIRCLE = 0; public static int TYPE_ROUND = 1; /** * 圆角大小的默认值 */ private static int BODER_RADIUS_DEFAULT = 10; /** * 绘图的Paint */ private Paint mBitmapPaint; /** * 圆角的半径 */ private int mRadius; /** * 3x3 矩阵,主要用于缩小放大 */ private Matrix mMatrix; /** * 渲染图像,使用图像为绘制图形着色 */ private BitmapShader mBitmapShader; /** * view的宽度 */ private int mWidth; private RectF mRoundRect; View view; public AndroidImageView(Context context, View view) : base(context) { this.view = view; mMatrix = new Matrix(); mBitmapPaint = new Paint(); mBitmapPaint.AntiAlias = true; //TypedArray a = context.obtainStyledAttributes(attrs, // R.styleable.RoundImageView); //mBorderRadius = a.getDimensionPixelSize( // R.styleable.RoundImageView_borderRadius, (int)TypedValue // .applyDimension(TypedValue.COMPLEX_UNIT_DIP, // BODER_RADIUS_DEFAULT, getResources() // .getDisplayMetrics()));// 默认为10dp //type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 默认为Circle //a.recycle(); } protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) { base.OnMeasure(widthMeasureSpec, heightMeasureSpec); ///** // * 如果类型是圆形,则强制改变view的宽高一致,以小值为准 // */ if (type == TYPE_CIRCLE) { mWidth = Math.Min(MeasuredWidth, MeasuredHeight); mRadius = mWidth / 2; SetMeasuredDimension(mWidth, mWidth); } } /** * 初始化BitmapShader */ private void setUpShader() { Drawable drawable = this.Drawable; if (drawable == null) { return; } Bitmap bmp = drawableToBitamp(drawable); if (bmp == null) { return; } // 将bmp作为着色器,就是在指定区域内绘制bmp mBitmapShader = new BitmapShader(bmp, Shader.TileMode.Clamp, Shader.TileMode.Clamp); float scale = 1.0f; // if (type == TYPE_CIRCLE) // { // // 拿到bitmap宽或高的小值 // int bSize = Math.Min(bmp.Width, bmp.Height); // scale = mWidth * 1.0f / bSize; // } // else if (type == TYPE_ROUND) // { // //Log.e("TAG", // //"b'w = " + bmp.getWidth() + " , " + "b'h = " // //+ bmp.getHeight()); // if (!(bmp.Width == Width && bmp.Height == Height)) // { // // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; // scale = Math.Max(Width * 1.0f / bmp.Width, // Height * 1.0f / bmp.Height); // } // } // // shader的变换矩阵,我们这里主要用于放大或者缩小 // mMatrix.SetScale(scale, scale); // // 设置变换矩阵 // mBitmapShader.SetLocalMatrix(mMatrix); // // 设置shader // mBitmapPaint.SetShader(mBitmapShader); //新方法 if (type == TYPE_CIRCLE) { // 拿到bitmap宽或高的小值 int bSize = Math.Min(bmp.Width, bmp.Height); scale = mWidth * 1.0f / bSize; // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.SetScale(scale, scale); } else if (type == TYPE_ROUND) { if (!(bmp.Width == Width && bmp.Height == Height)) { var scaleX = Width * 1.0f / bmp.Width; var scaleY = Height * 1.0f / bmp.Height; // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.SetScale(scaleX, scaleY); } else { // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.SetScale(scale, scale); } } // 设置变换矩阵 mBitmapShader.SetLocalMatrix(mMatrix); // 设置shader mBitmapPaint.SetShader(mBitmapShader); } protected override void OnDraw(Canvas canvas) { // Log.e("TAG", "onDraw"); if (Drawable == null) { return; } try { setUpShader(); if (type == TYPE_ROUND) { if (!view.IsSetAloneRadius) { canvas.DrawRoundRect(mRoundRect, view.Radius, view.Radius, mBitmapPaint); } else { canvas.DrawRoundRect(mRoundRect, view.mAloneRadius, view.mAloneRadius, mBitmapPaint); if ((view.mRadiusId & 1) == 0) { canvas.DrawRect(0, 0, view.mAloneRadius, view.mAloneRadius, mBitmapPaint); } if ((view.mRadiusId >> 1 & 1) == 0) { canvas.DrawRect(mRoundRect.Right - view.mAloneRadius, 0, mRoundRect.Right, view.mAloneRadius, mBitmapPaint); } if ((view.mRadiusId >> 2 & 1) == 0) { canvas.DrawRect(0, mRoundRect.Bottom - view.mAloneRadius, view.mAloneRadius, mRoundRect.Bottom, mBitmapPaint); } if ((view.mRadiusId >> 3 & 1) == 0) { canvas.DrawRect(mRoundRect.Right - view.mAloneRadius, mRoundRect.Bottom - view.mAloneRadius, mRoundRect.Right, mRoundRect.Bottom, mBitmapPaint); } } } else { canvas.DrawCircle(mRadius, mRadius, mRadius, mBitmapPaint); // drawSomeThing(canvas); } } catch { Shared.HDLUtils.WriteLine("error:ImageView OnDraw catch"); base.OnDraw(canvas); } } protected override void OnSizeChanged(int w, int h, int oldw, int oldh) { base.OnSizeChanged(w, h, oldw, oldh); // 圆角图片的范围 if (type == TYPE_ROUND) mRoundRect = new RectF(0, 0, w, h); } /** * drawable转bitmap * * @param drawable * @return */ private Bitmap drawableToBitamp(Drawable drawable) { if (drawable.GetType() == typeof(BitmapDrawable)) { BitmapDrawable bd = (BitmapDrawable)drawable; return bd.Bitmap; } int w = drawable.IntrinsicWidth; int h = drawable.IntrinsicHeight; if (w <= 0 || h <= 0) { return null; } Bitmap bitmap = Bitmap.CreateBitmap(w, h, Bitmap.Config.Argb8888); Canvas canvas = new Canvas(bitmap); drawable.SetBounds(0, 0, w, h); drawable.Draw(canvas); return bitmap; } private static string STATE_INSTANCE = "state_instance"; private static string STATE_TYPE = "state_type"; private static string STATE_BORDER_RADIUS = "state_border_radius"; protected override IParcelable OnSaveInstanceState() { Bundle bundle = new Bundle(); bundle.PutParcelable(STATE_INSTANCE, base.OnSaveInstanceState()); bundle.PutInt(STATE_TYPE, type); bundle.PutInt(STATE_BORDER_RADIUS, (int)view.Radius); return bundle; } protected override void OnRestoreInstanceState(IParcelable state) { if (state.GetType() == typeof(Bundle)) { Bundle bundle = (Bundle)state; base.OnRestoreInstanceState((IParcelable)bundle .GetParcelable(STATE_INSTANCE)); this.type = bundle.GetInt(STATE_TYPE); view.Radius = (uint)bundle.GetInt(STATE_BORDER_RADIUS); } else { base.OnRestoreInstanceState(state); } } public void setType(int type) { if (this.type != type) { this.type = type; if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE) { this.type = TYPE_CIRCLE; } RequestLayout(); } } public int dp2px(int dpVal) { return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dpVal, Resources.DisplayMetrics); } } }