본문 바로가기

프로그래밍/안드로이드

[안드로이드 팁] ScrollView 에 Gesture 이벤트를 달아보자

작업을 하다보니 ScrollView에 Gesture를 추가해야 하는 상황이 생기게 되더라구요.
기존 웹서핑을 하다보니 자세히 나와 있지 않아 나름 삽질을 하며 성공한 방법을 정리 하고자 합니다.
절대적인 방법이 아닌 혼자만의 삽질이니 더 좋은 방법이 있으시다면 알려주시면 수정하도록 하겠습니다.

당연히 Gesture를 가능하게 하려면 Activity에 Gesture를 상속받아 몇가지를 오버라이딩을 하여야 합니다.
public boolean onDown(MotionEvent e) {}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
  float velocityY) {}
public void onLongPress(MotionEvent e) {}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {}
public void onShowPress(MotionEvent e) {}
public boolean onSingleTapUp(MotionEvent e) {}

위의 메소드들은 오버라이딩을 해야 하죠. 각각의 메소드에 대한 설명은 api를 참고 하시구요.

아래는 기본적으로 되어 있는 Gesture관련 코드 입니다.
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.OnGestureListener;
import android.widget.Toast;

public class Test1 extends Activity implements OnGestureListener {
	private GestureDetector gd;
		
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		gd = new GestureDetector(this);
	}
		
	@Override
	public boolean onTouchEvent(MotionEvent event) {		
		return gd.onTouchEvent(event);
	}
	
	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

}
 
다음은 main.xml 코드 입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="fill_parent"
 android:layout_height="fill_parent">
<ViewFlipper 
 android:id="@+id/ViewFlipper01"
 android:layout_height="fill_parent"
 android:layout_width="fill_parent">
 <ScrollView
  android:id="@+id/ScrollView01"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <LinearLayout
   android:id="@+id/LinearLayout01"
   android:layout_height="fill_parent"
   android:layout_width="fill_parent">
   <TextView
    android:layout_width="fill_parent"
    android:text="@string/hello"
    android:layout_height="1600px"/>
  </LinearLayout>
 </ScrollView>
</ViewFlipper>
</LinearLayout>
 
 
참 무식한 코드죠..
여기에서 기본적으로 Gesture이벤트를 추가하기 위해서는 몇가지를 추가해야 합니다.
먼저 onCreate() 메소드 안에서 이벤트를 인지 할수 있도록 Viewflipper에다가 이벤트를 추가합니다.
ViewFlipper viewFlipper = (ViewFlipper)findViewById(R.id.ViewFlipper01);
ScrollView scrollView = (ScrollView)findViewById(R.id.ScrollView01);
scrollView.setOnTouchListener(this);
viewFlipper .setOnTouchListener(this);
 
이벤트를 등록하시고. 아래 메소드를 오버라이딩 하여야 합니다.
public boolean onTouch(View v, MotionEvent event){ }
보통 웹을 검색하시면 오버라이딩된 내용이
public boolean onTouch(View v, MotionEvent event){ 
  gd.onTouchEvent(event);
}
이래 되어 있죠. 그럼 ScrollView 이벤트는 죽어도~~~~ 안됩니다.
그리하여 이벤트를 분리 시킵니다.
참고로 전 좌우는 ViewFlipper, 상하는 ScrollView를 주기 위해 작성했구요.
반대로 하실분들은 동일한 방법으로 살짝 수정하시면 가능하실거에요.
무식한 저보다는 훨씬 수월하게 작업 하실수 있을 겁니다.
private float lastY = 0.0f;
@Override
 public boolean onTouch(View v, MotionEvent event) {
  // TODO Auto-generated method stub
  float y = event.getY();
  if (LastY != 0.0f && (Math.abs(LastY - y) > 15.0f)) {
   LastY = y;
   return onTouchEvent(event);
  } else {
   LastY =y;
   gd.onTouchEvent(event);
  }
  return true;
 }
위에서 처럼 코드를 수정하시면 이제 좌우스크롤과 상하 스크롤이 모두 적용되는걸 부실수 있을 겁니다.
간단히 말씀드리면 좌우 이벤트와 상하 이벤트를 구분하여 적용시키 주는 것이죠...
그럼 궁금하신것 댓글 달아 주시구요. 잘못된 곳역시 댓글 달아 주시면 저에게는 많은 도움이 될듯 합니다.