쓸줄은 안다...하지만 왜 그렇게 쓰는지 이해가 필요하다..
먼저...가장 무식한 방법이 아래에 있다.
package lee.hyeontae.HandlerAccess;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.TextView;
public class HandlerAccess extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout linear =
(LinearLayout)findViewById(R.id.linear);
linear.setOnTouchListener(new OnTouchListener() {
@Override
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;
}
});
}
}
|
Touch Event가 발생될때마다 findViewById 메서드를 호출하여 TextView를 검색한다. 매번 Resource를 뒤지는 과정은 .... 참 무식하다^^
그래도 개발잔데...좀더 영리한 방법을 사용하여 실행속도를 높여보자.
아래 개선된 방법이 있다.
package lee.hyeontae.HandlerAccess;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.TextView;
public class HandlerAccess extends Activity {
TextView text;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text =
(TextView)findViewById(R.id.text);
LinearLayout linear =
(LinearLayout)findViewById(R.id.linear);
linear.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN) {
text.setText("Touched");
return true;
}
return false;
}
});
}
}
|
TextView를 외부 클래스의 멤버로 선언해 두고 onCreate에서 딱 한번 findViewById 메서드를 호출하게 된다.
설명 하나를 더하자면 여기서 외부 클래스는 Activity가 되며, 이너 클래스는 리스너가 된다.
이 방법의 문제는 리스너가 많을 경우 외부 클래스의 멤버로 많은 변수들이 선언되며 이때 외부 클래스가 뚱뚱해진다...
그래서 나온 방법은 아래와 같다.
package lee.hyeontae.HandlerAccess;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;
import android.widget.TextView;
public class HandlerAccess extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView
text = (TextView)findViewById(R.id.text);
LinearLayout linear =
(LinearLayout)findViewById(R.id.linear);
linear.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN) {
text.setText("Touched");
return true;
}
return false;
}
});
}
}
|
final 지정자를 통해 TextView를 상수 처리를 해버렸다. 많약 final을 사용하지 않았다면 에러가 발생하지...
final 을 안쓰면 text변수는 onCreate가 리턴되면 사라진다. 하지만 리스너라는것은 등록을 시켜뒀다가 이벤트가 발생하는 시점에 실행되므로
이미 사라진 text변수를 호출 할 수 없게 되는것이다. 이를 방지하기 위해 final을 통해 상수처리를 하게 되면 onTouch를 등록하는 시점에
그 값이 전달되게 되고....그럼 터치가 발생하는 시점에 text의 값을 정상적으로 처리를 할 수 있지.
기억하자!!! 리스너로 전달하고 싶은 지역 변수엔 final !!!!