如何使用夹点缩放SurfaceView?我正在用C#学习Xamarin / Android。
这是我的代码:
namespace test_surfaceView
{
class SurfaceViewActivity : SurfaceView, ISurfaceHolderCallback, SurfaceView.IOnTouchListener
{
//private ImageViewActivity imageViewActivity;
private ScaleGestureDetector mScaleDetector;
private ScaleListener sListener;
private static float mScaleFactor = 0.6F;
private static float scalePointX;
private static float scalePointY;
private static int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
private static float mPosX, mPosY, mLastTouchX, mLastTouchY;
private Android.Graphics.Bitmap BitmapImage;
private Android.Graphics.Bitmap NEwBitmap;
private Canvas canvasS = new Canvas();
ISurfaceHolder surfaceHolder;
private Context mContext;
private Paint paint;
private byte[] byteArray;
private BitmapFactory.Options bmOptions;
public SurfaceViewActivity(Context context)
: base(context)
{
// TODO: Complete member initialization
Log.Debug("SurfaceMessage", "SurfaceViewActivity");
Log.Debug("mScaleFactor", "" + mScaleFactor);
Log.Debug("mScaleFactor", "" + mScaleFactor);
Log.Debug("scalePointX", "" + scalePointX);
Log.Debug("scalePointY", "" + scalePointY);
//SurfaceView surfaceView = FindViewById<SurfaceView>(Resource.Id.ImageView);
mContext = context;
surfaceHolder = Holder;
surfaceHolder.AddCallback(this);
}
public void SurfaceCreated(ISurfaceHolder holder)
{
Log.Debug("SurfaceMessage", "SurfaceCreated");
//SetOnTouchListener(this);
try
{
Thread dkdk = new Thread(new ThreadStart(run));
dkdk.Start();
}
catch (System.Exception ex)
{
Log.Debug("MESSAGE", "THREAD START FAIL");
}
}
private void run()
{
try
{
canvasS = surfaceHolder.LockCanvas(null);
doDraw(canvasS);
}
catch (System.Exception ex)
{
}
finally
{
if (canvasS != null)
{
surfaceHolder.UnlockCanvasAndPost(canvasS);
}
}
}
private void doDraw(Canvas canvas)
{
canvas.Scale(mScaleFactor, mScaleFactor, scalePointX, scalePointY);
canvas.Translate(mPosX, mPosY);
Paint paint = new Paint();
paint.AntiAlias = true;
byteArray = Base64.Decode(ImagePath.BitmapPath, Base64.Default);
bmOptions = new BitmapFactory.Options();
bmOptions.InSampleSize = 1;
bmOptions.InJustDecodeBounds = false;
bmOptions.InPurgeable = true;
BitmapImage = BitmapFactory.DecodeByteArray(byteArray, 0, byteArray.Length, bmOptions);
//Bitmap dkdk = new Bitmap();
NEwBitmap = Bitmap.CreateScaledBitmap(BitmapImage, 1300, 1900, true);
canvas.DrawBitmap(NEwBitmap, 0, 0, paint);
sListener = new ScaleListener();
mScaleDetector = new ScaleGestureDetector(mContext, sListener);
mScaleFactor = 500F / (float)Math.Min(Resources.DisplayMetrics.WidthPixels, Resources.DisplayMetrics.HeightPixels);
this.SetOnTouchListener(this);
}
public void SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format format, int width, int height)
{
Log.Debug("SurfaceMessage", "SurfaceChanged");
Log.Debug("SurfaceMessage", "width" + width);
Log.Debug("SurfaceMessage", "height" + height);
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
Log.Debug("SurfaceMessage", "SurfaceDestroyed");
BitmapImage = null;
}
private class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener
{
public override bool OnScale(ScaleGestureDetector detector)
{
scalePointX = detector.FocusX;
scalePointY = detector.FocusY;
mScaleFactor *= detector.ScaleFactor;
mScaleFactor = Math.Max(0.5f, Math.Min(mScaleFactor, 7.0f));
return true;
}
}
public bool OnTouch(View v, MotionEvent e)
{
mScaleDetector.OnTouchEvent(e);
switch (e.Action & MotionEventActions.Mask)
{
case MotionEventActions.Down:
Log.Debug("MotionEventActions", "Down");
float x = (e.GetX() - scalePointX) / mScaleFactor;
float y = (e.GetY() - scalePointY) / mScaleFactor;
mLastTouchX = x;
mLastTouchY = y;
mActivePointerId = e.GetPointerId(0);
break;
case MotionEventActions.Move:
Log.Debug("MotionEventActions", "Move");
int pointerIndex = e.FindPointerIndex(mActivePointerId);
float x2 = (e.GetX(pointerIndex) - scalePointX) / mScaleFactor;
float y2 = (e.GetY(pointerIndex) - scalePointY) / mScaleFactor;
float dx = (x2 - mLastTouchX);
float dy = (y2 - mLastTouchY);
if (!mScaleDetector.IsInProgress)
{
mPosX += dx;
mPosY += dy;
mLastTouchX = x2;
mLastTouchY = y2;
}
//this.Invalidate();
//PostInvalidate();
break;
case MotionEventActions.Up:
Log.Debug("MotionEventActions", "Up");
mActivePointerId = INVALID_POINTER_ID;
break;
case MotionEventActions.Cancel:
Log.Debug("MotionEventActions", "Cancel");
mActivePointerId = INVALID_POINTER_ID;
break;
case MotionEventActions.PointerUp:
Log.Debug("MotionEventActions", "PointerUp");
int pointerIndex2 = (int)(e.Action & MotionEventActions.PointerIndexMask) >> (int)MotionEventActions.PointerIndexShift;
int pointerID = e.GetPointerId(pointerIndex2);
if (pointerID == mActivePointerId)
{
int newPointerIndex = pointerIndex2 == 0 ? 1 : 0;
mLastTouchX = (e.GetX(newPointerIndex) - scalePointX) / mScaleFactor;
mLastTouchY = (e.GetY(newPointerIndex) - scalePointY) / mScaleFactor;
mActivePointerId = e.GetPointerId(newPointerIndex);
}
break;
}
return true;
}
}
}