Android

TouchEvent 사용법

Ms_Tony 2016. 3. 31. 12:17

TouchEvent를 사용 예제.

어플리케이션을 개발하다보면 터치를 통해 버튼을 누를 수도 있지만, 

그 외 다양한 기능을 수행해야 하는 경우도 생기게 됩니다.

가령 그 자리에 이미지를 올린다거나, 특정 제스쳐를 취하게 될 수도 있겠죠??

간단한 코드이니 코드에 달아놓은 주석으로 설명을 대체하겠습니다.


처음으로는 View를 상속받아 터치를 하였을 경우 처리를 하기 위한 CustomView를 만들 것입니다.

TipsView.java

/**
* Created by TonyChoi on 2016. 3. 31..
*/
public class TipsView extends View {

//터치 할 때 화면에 표현되는 점
private Paint mPaint = null;
//터치 한 곳의 좌표를 저장할 변수
private float x = -1, y = -1;

//java Code에서 뷰를 생성 할 떄 호출되는 생성자
public TipsView(Context context) {
super(context);

//표현될 점을 빨간색으로 표현하기 위해 Paint객체 생성
mPaint = new Paint();
//Paint의 경계면을 부드럽게 처리할 지 설정(boolean)
mPaint.setAntiAlias(true);
//Paint의 색 설정
mPaint.setColor(Color.RED);
}

//xml에서 뷰를 생성할 때 호출되는 생성자
public TipsView(Context context, AttributeSet attrs) {
super(context, attrs);

//내용은 위에 동일
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
}

//뷰에 그림 그리는 행위를 담당하는 메소드
protected void onDraw(Canvas canvas) {
//뷰의 배경색을 흰색으로 칠한다
canvas.drawColor(Color.WHITE);

//터치 행위가 발생한 경우 해당 위치에 원을 그린다
if (x > 0 && y > 0) {
// (x - 5, y - 5)를 시작으로 지름이 10인 원을 그린다.
canvas.drawCircle(x - 5, y - 5, 10, mPaint);
}
}

//터치 이벤트를 처리하는 콜백 메소드
public boolean onTouchEvent(MotionEvent event) {
//상위 클래스인 View 클래스에 발생한 이벤트를 전달
super.onTouchEvent(event);

//어떤 이벤트가 처리했는지에 따라 처리를 달리함
switch (event.getAction()) {
//Action Down이 발생 했을 경우
case MotionEvent.ACTION_DOWN :
//Action Down 한 위치의 x, y좌표를 받아와 변수에 저장한다
x = event.getX();
y = event.getY();
//뷰를 갱신
invalidate();
break;
//Action Move를 설정하고 싶은 경우 이곳에 코딩
case MotionEvent.ACTION_MOVE :
break;

//Action Up이 발생한 경우
case MotionEvent.ACTION_UP :
//Up이 발생한 경우 그리기 좌표에 -1을 저장하고 뷰를 갱신한다
y = x = -1;
//뷰를 갱신
invalidate();
break;
}

//true를 반환하여 더이상의 이벤트 처리가 이루어지지 않도록 완료한다
return true;
}
}

그 다음으로 코딩 할 것은 activity_main.xml입니다.


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/RL"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.project9.touchevent.MainActivity">

<com.project9.touchevent.TipsView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/tipsView"/>

<TextView
android:id="@+id/tvCoord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

</RelativeLayout>


마지막으로 MainActivity.java입니다.

public class MainActivity extends AppCompatActivity implements View.OnTouchListener{

//좌표를 출력할 텍스트뷰
private TextView mTvCoord;
//터치 위에 원이 그려지는 사용자 정의 뷰
private TipsView mTipsView;

//터치 이벤트의 좌표를 받아올 변수
private float x = -1, y = -1;
//최상단 RelativeLayout
private RelativeLayout RL;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//xml에 정의한 뷰들을 불러옴
RL = (RelativeLayout)findViewById(R.id.RL);
mTvCoord = (TextView)findViewById(R.id.tvCoord);
mTipsView = (TipsView)findViewById(R.id.tipsView);

//텍스트뷰에 텍스트 삽입
mTvCoord.setText("Touch!!!");
//Tips뷰를 터치 클릭 리스너 등록
mTipsView.setOnTouchListener(this);

}


@Override
public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {
//Down이 발생한 경우
case MotionEvent.ACTION_DOWN :
x = event.getX();
y = event.getY();

//내가 누른 자리의 좌표를 String 값으로 표현할 변수
String str;
str = "Coordinate : ( " + (int)x + ", " + (int)y + " )";
mTvCoord.setText(str);
//터치 한 곳에 이미지를 표현하기 위해 동적으로 ImageView 생성
ImageView img = new ImageView(this);
img.setImageResource(R.drawable.alert_red);

//이미지가 저장될 곳의 x,y좌표를 표현
img.setX(x-40);
img.setY(y - 90);
//최상단 릴레이티브 레이아웃에 이미지를 Add
RL.addView(img);
break;
//Up이 발생한 경우
case MotionEvent.ACTION_UP :
mTvCoord.setText("Touch !!!");
break;

}
//false를 반환하여 뷰 내에 재정의한 onTouchEvent 메소드로 이벤트를 전달한다
return false;
}
}


이렇게 코딩을 하게되면 아래 스크린샷과 같이 터치를 하였을 때

그자리에 자신이 설정한 이미지가 들어가게됩니다.

또한 위에 Touch텍스트가 ACTION_DOWN상태 일 때는

자신이 누르고 있는 화면상의 좌표가 어디인지 알려주기도 합니다.

마지막으로 소스코드 올리면서 이만 마무리하겠습니다.

TouchEvent.zip