Download presentation
Presentation is loading. Please wait.
Published by罡 雷 Modified 6년 전
2
Contents 학습목표 이벤트를 처리하는 여러 가지 형식과 각 형식의 장단점에 대해 상세하게 연구하고 기본적인 이벤트에 대한 실습을 한다. 사용자의 입력을 자유자재로 처리하기 위해서 반드시 습득해야 하는 중요한 기술 실습. 학습내용 이벤트 핸들러 여러 가지 이벤트
3
6.1.1 이벤트 처리 콜백 메서드 재정의 리스너 인터페이스 구현 액티비티가 리스너 구현 뷰가 리스너 구현
GUI 환경은 비절차적이며 사용자의 입력에 반응하는 이벤트를 처리하는 식으로 코드를 작성한다. 이벤트를 작성하는 여러 가지 방법과 문법적 변형이 존재한다. 각 방법이 혼용되므로 모든 방식에 대해 익숙해질 필요가 있다. 콜백 메서드 재정의 리스너 인터페이스 구현 액티비티가 리스너 구현 뷰가 리스너 구현 익명 이너 클래스 사용 익명 이너 클래스의 임시 객체 사용
4
해당 클래스를 상속 받아 콜백 메서드에서 재정의 특정 이벤트가 발생했을 때 시스템에 의해 자동으로 호출되는 매서드.
6.1.1 이벤트 처리 – 1. 콜백 메서드 재정의 해당 클래스를 상속 받아 콜백 메서드에서 재정의 특정 이벤트가 발생했을 때 시스템에 의해 자동으로 호출되는 매서드. 특정 이벤트가 발생한 시점을 정확하게 가로챌 수 있으며, 이벤트 발생시 동작을 정의할 수 있다. 사용자와 상호 작용하는 주체가 뷰이므로 이벤트 콜백은 주로 뷰가 제공 boolean onTouchEvent (MotionEvent event) boolean onKeyDown (int keyCode, KeyEvent event) boolean onKeyUp (int keyCode, KeyEvent event) boolean onTrackballEvent (MotionEvent event)
5
6.1.1 이벤트 처리 – 2. 리스너 인터페이스 구현 리스터(Listener) : 특정 이벤트를 처리하는 인터페이스.
대응되는 이벤트를 받는 단 하나의 메서드가 선언되어 있다. 대표적인 몇가지 리스너와 리스너에 선언된 메서드는 다음과 같다. View.OnTouchListener : boolean onTouch (View v, MotionEvent event) View.OnKeyListener : boolean onKey (View v, int keyCode, KeyEvent event) View.OnClickListener : void onClick (View v) View.OnLongClickListener : boolean onLongClick (View v) View.OnFocusChangeListener : void onFocusChange (View v, boolean hasFocus) 이벤트를 처리하려면 리스너를 구현하는 클래스를 선언, 그 객체를 생성해야 한다. 등록 메서드는 “ Set + 리스너 “ 상속을 받지 않아도 임의의 클래스가 구현 가능하다. 별도의 리스너 클래스를 구현하고 리스너 객체를 생성해야 한다는 면에서 번거롭다.
6
6.1.1 이벤트 처리 – 3. 액티비티에서 4.뷰에서 구현 3. 액티비티에서 리스너 구현 4. 뷰에서 리스너 구현
액티비티는 Activity클래스를 이미 상속 받았지만 인터페이스는 개수에 상관없이 얼마든지 상속받을 수 있다. 4. 뷰에서 리스너 구현 뷰를 상속받을 경우 뷰도 리스너를 구현 할 수 있다. 자신의 이벤트를 스스로 처리한다는 면에서 기동성 향상. 뷰를 상속받을 경우에만 이 기법을 쓸 수 있다.
7
6.1.1 이벤트 처리 – 5. 익명 이너 클래스 사용 익명 이너 클래스 문법을 활용하여 리스너 클래스 선언을 생략한다.
리스너 생성을 위해 한번만 사용할 클래스 이므로 두 개 이상의 리스너는 만들 수 없다. 익명 이너 클래스 정의 하는 문법은 다음과 같다. 일반적인 코드 축약된 코드 Class MyClass implements Interface { 메서드 구현 } MyClass obj = new MyClass ( ); Interface obj = new Interface( ) { };
8
6.1.1 이벤트 처리 – 6. 익명 이너 클래스의 임시 객체 사용
리스너 객체 두 개 이상 생성할 필요가 없다. 이름없는 임시 객체로 생성하여 set 메서드의 인수로 전달한다. 짧고 간단하지만 형식이 생소하다. 이름 있는 객체 사용 임시 객체 사용 Class obj = new Class( ); Method(obj); Method(new Class( ) );
9
6.1.1 이벤트 처리 – 1. 콜백 메서드 재정의 C06_HandleEvent .java public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View vw = new MyView(this); setContentView(vw); } protected class MyView extends View { public MyView(Context context) { super(context); public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(MainActivity.this,"Touch Event Received", Toast.LENGTH_SHORT).show(); return true; return false;
10
6.1.1 이벤트 처리 – 2. 리스너 인터페이스 구현 C06_HandleEvent .java public class C06_HandleEvent extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View vw = new View(this); // 3.리스너 등록 vw.setOnTouchListener(TouchListener); setContentView(vw); } // 1.리스너 구현 클래스 선언 class TouchListenerClass implements View.OnTouchListener { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(C06_HandleEvent.this,"Touch Event Received", Toast.LENGTH_SHORT).show(); return true; return false; // 2.리스너 객체 생성 TouchListenerClass TouchListener = new TouchListenerClass();
11
6.1.1 이벤트 처리 – 3. 액티비티가 리스너 구현 C06_HandleEvent .java public class C06_HandleEvent extends Activity implements View.OnTouchListener { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View vw = new View(this); vw.setOnTouchListener(this); setContentView(vw); } public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(this,"Touch Event Received", Toast.LENGTH_SHORT).show(); return true; return false;
12
6.1.1 이벤트 처리 – 4. 뷰가 리스너 구현 C06_HandleEvent .java public class C06_HandleEvent extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyView vw = new MyView(this); vw.setOnTouchListener(vw); setContentView(vw); } protected class MyView extends View implements View.OnTouchListener { public MyView(Context context) { super(context); } public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(C06_HandleEvent.this,"Touch Event Received“, Toast.LENGTH_SHORT).show(); return true; return false;
13
6.1.1 이벤트 처리 – 5. 뷰가 리스너 구현 C06_HandleEvent .java public class C06_HandleEvent extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View vw = new View(this); vw.setOnTouchListener(TouchListener); setContentView(vw); } private View.OnTouchListener TouchListener = new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(C06_HandleEvent.this,"Touch Event Received", Toast.LENGTH_SHORT).show(); return true; return false; };
14
6.1.1 이벤트 처리 – 6. 뷰가 리스너 구현 C06_HandleEvent .java public class C06_HandleEvent extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View vw = new View(this); vw.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(C06_HandleEvent.this,"Touch Event Received", Toast.LENGTH_SHORT).show(); return true; } return false; }); setContentView(vw);
15
6.1.2 핸들러의 우선 순위 C06_HandlerOrder.java
public class C06_HandlerOrder extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View vw = new MyView(this); //* 리스너 - 1순위 vw.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(C06_HandlerOrder.this,"Listener : Touch Event Received", Toast.LENGTH_SHORT).show(); return true; } return false; }); //*/ setContentView(vw); protected class MyView extends View { public MyView(Context context) { super(context); C06_HandlerOrder.java //* 뷰의 콜백 메서드 - 2순위 public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Toast.makeText(C06_HandlerOrder.this,"View : Touch Event Received", Toast.LENGTH_SHORT).show(); return true; } return false; //*/ //* 액티비티의 콜백 메서드 - 3순위 Toast.makeText(C06_HandlerOrder.this,"Activity : Touch Event Received",
16
액티비티의 onTouchEvent 콜백 메서드
6.1.2 핸들러의 우선 순위 이벤트 핸들러가 중복 정의되었을 경우 미리 정한 우선순위에 따라 적절한 핸들러를 선택 호출 한다. 범위가 좁은 핸들러가 먼저 호출한다. 우선 순위의 핸들러에서 true를 리턴하면 다음 순위는 호출되지 않는다. 뷰의 리스너 뷰의 onTouchEvent 콜백 메서드 액티비티의 onTouchEvent 콜백 메서드
17
6.1.3. 외부 변수 액세스 리스너는 등록하는 메서드의 지역 메서드가 아니다.
리스너의 실행 시점은 등록 시점이 아니라 이벤트 발생시점이다. 리스너에서 외부 객체의 멤버는 자유롭게 참조할 수 있다. 리스너가 등록 메서드의 지역 변수를 참조하려면 final 지정자가 필요하다. final은 지역 변수와 리스너의 존재 기간을 일치시킨다.
18
findViewById 메서드는 리소스를 뒤져 뷰를 찾아내는 복잡한 동작을 하므로 느리다.
외부 변수 액세스 C06_HandlerAccess.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#cccccc" > <TextView android:layout_height="wrap_content" android:text="핸들러에서 외부 변수 액세스 테스트" android:textColor="#000000" /> </LinearLayout> C06_HandlerAccess.java /* 핸들러내의 지역 변수로 선언하기 public class C06_HandlerAccess extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.c06_handleraccess); LinearLayout linear = (LinearLayout)findViewById(R.id.linear); linear.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { TextView text = (TextView)findViewById(R.id.text); text.setText("Touched"); return true; } return false; }); findViewById 메서드는 리소스를 뒤져 뷰를 찾아내는 복잡한 동작을 하므로 느리다.
19
멤버변수로 지정 : 많아지면 코드가 뚱뚱해진다.
외부 변수 액세스 C06_HandlerAccess.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#cccccc" > <TextView android:layout_height="wrap_content" android:text="핸들러에서 외부 변수 액세스 테스트" android:textColor="#000000" /> </LinearLayout> C06_HandlerAccess.java /* 멤버로 선언해 놓기 public class C06_HandlerAccess extends Activity { TextView mText; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.c06_handleraccess); mText = (TextView)findViewById(R.id.text); LinearLayout linear = (LinearLayout)findViewById(R.id.linear); linear.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mText.setText("Touched"); return true; } return false; }); //*/ 멤버변수로 지정 : 많아지면 코드가 뚱뚱해진다.
20
지역변수로 선언(이너클래스에서 참조하기 위해서는 final을 선언해야 한다.)
외부 변수 액세스 C06_HandlerAccess.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#cccccc" > <TextView android:layout_height="wrap_content" android:text="핸들러에서 외부 변수 액세스 테스트" android:textColor="#000000" /> </LinearLayout> C06_HandlerAccess.java /* 핸들러를 포함한 메서드의 지역 변수 사용 public class C06_HandlerAccess extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.c06_handleraccess); final TextView outText = (TextView)findViewById(R.id.text); LinearLayout linear = (LinearLayout)findViewById(R.id.linear); linear.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { outText.setText("Touched"); return true; } return false; }); //*/ 지역변수로 선언(이너클래스에서 참조하기 위해서는 final을 선언해야 한다.)
21
onCreate에 있던 리스너 코드를 SetTouchHandler라는 메서드로 분리했다.
외부 변수 액세스 C06_HandlerAccess.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#cccccc" > <TextView android:layout_height="wrap_content" android:text="핸들러에서 외부 변수 액세스 테스트" android:textColor="#000000" /> </LinearLayout> C06_HandlerAccess.java /* 핸들러를 포함한서브 메서드의 인수 사용 public class C06_HandlerAccess extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.c06_handleraccess); TextView outText = (TextView)findViewById(R.id.text); SetTouchHandler(outText); } void SetTouchHandler(TextView tv) { final TextView fText = tv; LinearLayout linear = (LinearLayout)findViewById(R.id.linear); linear.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { fText.setText("Touched"); return true; return false; }); //*/ onCreate에 있던 리스너 코드를 SetTouchHandler라는 메서드로 분리했다.
22
리스너로 전달하는 지역 변수를 final로 받았다.
외부 변수 액세스 C06_HandlerAccess.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#cccccc" > <TextView android:layout_height="wrap_content" android:text="핸들러에서 외부 변수 액세스 테스트" android:textColor="#000000" /> </LinearLayout> C06_HandlerAccess.java //* 핸들러를 포함한서브 메서드의 final 인수 사용 public class C06_HandlerAccess extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.c06_handleraccess); TextView outText = (TextView)findViewById(R.id.text); SetTouchHandler(outText); } void SetTouchHandler(final TextView tv) { LinearLayout linear = (LinearLayout)findViewById(R.id.linear); linear.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { tv.setText("Touched"); return true; return false; }); //*/ 리스너로 전달하는 지역 변수를 final로 받았다.
Similar presentations