Tuesday, November 27, 2012

A simple multitouch view for MonoDroid

I needed a multitouch view for MonoDroid (Mono for Android), so I built one :)

I based it on
http://android-er.blogspot.co.uk/2011/05/detect-multi-touch-on-custom-view.html

It seems to work quite well - to see it in action, just include it in your project and then you can use it in your axml or in your C#


The code:

using Android.Content;
using Android.Graphics;
using Android.Util;
using Android.Views;
namespace Cirrious.Sphero.WorkBench.UI.Droid.Controls
{
// adapted from http://android-er.blogspot.co.uk/2011/05/detect-multi-touch-on-custom-view.html
public class TouchView : View
{
private const int MaximumTouchCount = 2;
private readonly Paint _paint = new Paint(PaintFlags.AntiAlias);
private readonly float[] _x = new float[MaximumTouchCount];
private readonly float[] _y = new float[MaximumTouchCount];
private readonly bool[] _isTouch = new bool[MaximumTouchCount];
public TouchView(Context context)
: base(context)
{
}
public TouchView(Context context, IAttributeSet attrs)
: base(context, attrs)
{
}
public TouchView(Context context, IAttributeSet attrs, int defStyle)
: base(context, attrs, defStyle)
{
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
SetMeasuredDimension(MeasureSpec.GetSize(widthMeasureSpec), MeasureSpec.GetSize(heightMeasureSpec));
}
protected override void OnDraw(Canvas canvas)
{
_paint.StrokeWidth = 1;
_paint.SetStyle(Paint.Style.Fill);
if (_isTouch[0])
{
_paint.Color = Color.Red;
canvas.DrawCircle(_x[0], _y[0], 75f, _paint);
}
if (_isTouch[1])
{
_paint.Color = Color.Blue;
canvas.DrawCircle(_x[1], _y[1], 75f, _paint);
}
}
public override bool OnTouchEvent(MotionEvent motionEvent)
{
var pointerIndex = ((int) (motionEvent.Action & MotionEventActions.PointerIdMask) >>
(int) MotionEventActions.PointerIdShift);
var pointerId = motionEvent.GetPointerId(pointerIndex);
var action = (motionEvent.Action & MotionEventActions.Mask);
var pointCnt = motionEvent.PointerCount;
if (pointCnt <= MaximumTouchCount)
{
if (pointerIndex <= MaximumTouchCount - 1)
{
for (var i = 0; i < pointCnt; i++)
{
var id = motionEvent.GetPointerId(i);
_x[id] = (int) motionEvent.GetX(i);
_y[id] = (int) motionEvent.GetY(i);
}
switch (action)
{
case MotionEventActions.Down:
case MotionEventActions.PointerDown:
case MotionEventActions.Move:
_isTouch[pointerId] = true;
break;
default:
_isTouch[pointerId] = false;
break;
}
}
}
Invalidate();
return true;
}
}
}
view raw TouchView.cs hosted with ❤ by GitHub
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<cirrious.sphero.workbench.ui.droid.controls.TouchView
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</FrameLayout>
view raw View.axml hosted with ❤ by GitHub

No comments:

Post a Comment