using System;
|
using Android.Content;
|
using Android.Graphics;
|
using Android.Graphics.Drawables;
|
using Android.OS;
|
using Android.Util;
|
using Android.Views;
|
|
namespace Shared
|
{
|
//已经全面检查了代码
|
/// <summary>
|
/// Button 按键
|
/// </summary>
|
public class ImageView : View
|
{
|
/// <summary>
|
/// 当前视图
|
/// </summary>
|
/// <value>The android button.</value>
|
AndroidImageView currentButton
|
{
|
get
|
{
|
return AndroidView as AndroidImageView;
|
}
|
set
|
{
|
AndroidView = value;
|
}
|
}
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public ImageView()
|
{
|
currentButton = new AndroidImageView(Application.Activity, this);
|
}
|
|
internal string imagePath, tempImagePath;
|
/// <summary>
|
/// 非选中状态的背景图路径
|
/// </summary>
|
/// <value>The un selected image path.</value>
|
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);
|
}
|
}
|
}
|