◎위챗 : speedseoul
http://blog.naver.com/aiger?Redirect=Log&logNo=100149726744
안드로이드는 Dialog와 Toast 두 개로 메시지창을 많이 띄웁니다.
그중에 많이 쓰이는게 Dialog죠.
이렇게 쓰면 좀 더 편하지 않을까 해서 샘플 소스 올려봅니다.
1. onCreateDialog
: dialog 생성할때 많이 오버라이드해서 쓰실거라 생각됩니다. 한 함수내에서 다이얼로그를 관리할 수 있다는 면에선 좋지만 단점이 존재하죠.
로그를 찍어보시면 아시겠지만, 한번 onCreateDialog로 생성된 다이얼로그는 다시 onCreateDialog를 타지 않습니다. 한번 생성이 되면 액티비티안에서 관리가 되는걸로 보여집니다. DatePickerDialog를 onCreateDialog안에서 생성해 보시면 생성된 후 날짜를 변경하고 다시 showDialog시키면 이전에 변경된 날짜로 표시되는걸 확인하실 수 있습니다.
다시 쓰지 않는 다이얼로그는 아래와 같이 설정해서 삭제해줘야 합니다.
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
// TODO Auto-generated method stub
super.onPrepareDialog(id, dialog);
switch (id) {
case //해당 다이얼로그 id
removeDialog(id);
}
}
2. OnDismissListener
: 액티비티의 onCreateDialog로 다이얼로그 객체를 만드는 부분은 모을 수 있지만, 다이얼로그마다 ok버튼리스너, cancel버튼리스너를 다이얼로그마다 설정해야 하는 번거로움이 있습니다.
그럴때 사용하면 유용한게 OnDismissListener입니다.
dialog를 상속받은 클래스를 만든 후
private OnDismissListener mConfirmListener = null;
public ConfirmMsgDialog(Context context, CharSequence message, OnDismissListener confirmListener) {
super(context, R.style.theme_Dialog); //theme는 Style로 지정
struct(context);
setMessage(message);
mConfirmListener = confirmListener;
}
private void construct(Context context) {
//커스톰이 아닐시 리스너만 전달
if (mConfirmListener != null) {
setOnDismissListener(mConfirmListener);
}
dismiss();
setContentView(R.layout.confirm_msg_dialog); //커스톰이라면 layout을 변경
((TextView) findViewById(android.R.id.title)).setVisibility(View.GONE); //타이틀 미표시
Button button;
button = (Button) findViewById(R.id.ok); //커스톰일 경우 해당 ok버튼을 클릭시 dismissListener호출
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mConfirmListener != null) {
setOnDismissListener(mConfirmListener);
}
dismiss();
}
});
}
그리고 액티비티내에서 다이얼로그를 호출시 new ConfirmMsgDialog(context, "메시지", okListener);
private OnDismissListener okListener= new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
//확인버튼 누를시 실행할 코드
}
};
okListener는 다른 다이얼로그에도 적용이 가능하므로 재활용할 수 있습니다.
//백키와 메뉴롱키도 막게 할 수 있습니다. (메뉴롱키를 누르면 다이얼로그가 사라집니다) 프로그레스바처럼 뭔가를 실행중일때 프로그레스다이얼로그만 사라지는 사태가 생기면 안되겠죠~
public void backKeyLongKeyBlock()
{
this.setOnCancelListener(new OnCancelListener(){
@Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
}
});
this.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
if(event.isLongPress())
{
return true;
}
break;
}
return false;
}
});
}
3. window leap 에러
: 다이얼로그를 쓰다보면 자주 발생하는 ANR - window leap에러입니다. 다이얼로그가 액티비티에 종속적이기 때문에 발생하는 걸로 생각됩니다.
발생하는 이유는 다이얼로그가 떠 있는 상태에서 액티비티가 종료될 경우 발생하죠.
해당 액티비티가 종료되는 시점 onDestroy함수에서 해당 다이얼로그를 dismiss()시켜야 발생하지 않습니다.
[출처] Dialog 관련 샘플 소스|작성자 세뮤렐