1. 새로운 뷰 만들기
먼저 기본 뷰를 사용하지 않을 것이므로 새로운 뷰를 만들어야 합니다.
public class TouchView : Android.Views.View { public TouchView(Context context) : base(context) { } }
그리고 이 뷰를 앱에 세팅시켜야겠죠.
protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); // Set our view from the "main" layout resource SetContentView (Resource.Layout.Main);
이 부분을
protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); SetContentView(new TouchView(this));
이대로 실행해 보면 다음과 같이 아무것도 없는 화면만이 나타납니다.
2. 터치이벤트 처리
터치이벤트를 처리하는 메소드는 이미 Android.Views.View에 포함되어 있습니다. 우리가 할 일은 이 메소드를 재정의하는 일입니다.
public class TouchView : Android.Views.View
{
public TouchView(Context context) : base(context)
{
}
public override bool OnTouchEvent(MotionEvent e)
{
return true;
}
}
클릭정보는 MotionEvent e를 통해서 들어옵니다. 여러가지 정보가 있지만 중요한 것은 다음과 같습니다.
① e.Action
어떤 이벤트가 일어났는지를 구분하는 enum입니다. 여러가지가 있지만, 지금 당장 필요한 것은 다음과 같은 세개입니다.
- Android.Views.MotionEventActions.Down : 화면을 터치할때 일어나는 이벤트
- Android.Views.MotionEventActions.Up : 화면에서 손을 뗄때 일어나는 이벤트
- Android.Views.MotionEventActions.Move : 화면에서 움직일때 일어나는 이벤트
② e.GetX(), e.GetY()
이벤트가 어디서 일어났는지 알려주는 부분입니다.
3. 화면출력
일단 이벤트가 일어났는데, 이벤트가 일어났는지 안일어났는지 밖에서는 알 수가 없겠죠. 그래서 간단하게 이벤트를 출력하는 부분을 만들어야 합니다.
OnDraw()에서는 canvas에 여러가지 작업을 하면 그것이 화면에 나타나게 됩니다.
이 프로젝트에서 하는 일은 화면에 글을 쓰는 일입니다. 그 작업은 다음과 같은 함수로 할 수 있습니다.
public virtual void DrawText(string text, float x, float y, Paint paint);
이 외에도 몇가지 함수가 더 있는데 우선 이것만 보기로 하죠. public class TouchView : Android.Views.View
{
public TouchView(Context context) : base(context)
{
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
}
public override bool OnTouchEvent(MotionEvent e)
{
return true;
}
}
이 프로젝트에서 하는 일은 화면에 글을 쓰는 일입니다. 그 작업은 다음과 같은 함수로 할 수 있습니다.
public virtual void DrawText(string text, float x, float y, Paint paint);
일어난 이벤트 종류와 위치를 화면에 출력하는 TouchView 클래스입니다.
public class TouchView : Android.Views.View
{
private string eventAction;
private float getX, getY;
private Paint pen;
public TouchView(Context context) : base(context)
{
pen = new Paint();
pen.Color = Color.Yellow;
pen.TextSize = 30;
eventAction = "";
}
protected override void OnDraw(Canvas canvas)
{
canvas.DrawText("Touch Event " + eventAction, 10, 100, pen);
canvas.DrawText("Get " + getX + ',' + getY, 10, 150, pen);
}
public override bool OnTouchEvent(MotionEvent e)
{
eventAction = e.Action.ToString();
getX = e.GetX();
getY = e.GetY();
Invalidate();
return true;
}
}
4. 핀치(Pinch)
핀치(Pinch)란, 두 손가락을 사용해서 화면을 축소확대하는 기능을 말합니다. 그러기 위해서는 좌표를 두개 받을 수 있어야 합니다.
MotionEvent e의 프로퍼티 PointerCount가, 터치점이 몇개인지 받아오는 프로퍼티입니다. 두 손가락으로 터치하면 2, 세 손가락으로 터치하면 3, ..., 양 손 손가락을 다 동원하면 10도 될 수 있습니다.
그리고 각 손가락의 이벤트 위치는 e.GetX(int p), e.GetY(int p) 함수로 얻어올 수 있습니다.
그러므로 모든 터치입력을 받기 위해서는 다음과 같이 리스트를 사용해야 합니다.
public class TouchView : Android.Views.View
{
private List<string> eventAction = new List<string>();
private List<float> getX = new List<float>();
private List<float> getY = new List<float>();
private Paint pen;
public TouchView(Context context) : base(context)
{
pen = new Paint();
pen.Color = Color.Yellow;
pen.TextSize = 30;
for(int k = 0; k < 10; ++k)
eventAction.Add("");
}
protected override void OnDraw(Canvas canvas)
{
int row = 100;
foreach (var e in eventAction)
{
canvas.DrawText("Touch Event [" + e + "] ", 10, row, pen);
row += 50;
}
row += 50;
for (int k = 0; k < getX.Count; ++k)
{
canvas.DrawText("Get " + getX[k] + ',' + getY[k], 10, row, pen);
row += 50;
}
}
public override bool OnTouchEvent(MotionEvent e)
{
eventAction.RemoveAt(0);
eventAction.Add(e.Action.ToString() + ' ' + e.PointerCount.ToString());
getX.Clear();
getY.Clear();
for (int k = 0; k < e.PointerCount; ++k)
{
getX.Add(e.GetX(k));
getY.Add(e.GetY(k));
}
Invalidate();
return true;
}
}
이 앱을 폰으로 옮겨 실행한 결과입니다.
조금 낯선 이벤트가 있네요. Pointer1Up, Pointer2Up 같은 것 말입니다.
폰에서는 손가락을 고정시켜도 Move이벤트가 계속 들어오므로 Move이벤트는 빼고, 차례로 6개의 손가락을 터치했다가 다시 하나씩 뗀 결과입니다.
보시다시피 차례로 Down(손가락 터치), Pointer2Down(두번째 손가락 터치), Pointer3Down(세번째 손가락 터치) 순으로 들어오는 것을 알 수 있습니다. 이후의 숫자들은 Enum이 정의되어 있지 않은 것이고 말입니다.
그리고 손가락을 뗄 때는 몇번째로 터치했던 손가락이 떨어졌는지가 Pointer?Up의 형태로 오는 모양네요.
뭐 스마트폰 쓰면서 3개의 터치도 필요한 적이 없으니 그 이상의 Enum을 정하지 않은 것이겠죠.




댓글 없음:
댓글 쓰기