본문 바로가기

IT

젤리빈기반에서 DatePickerDialog 에서 취소버튼 이벤트 처리하는 방법

반응형

 젤리빈으로 롬업데이트가 활발한 요즘, 개발자들은 이전보다 더 많은 것을 신경쓰고 이벤트처리에 신경을 써야 합니다. 가장 많은 골머리를 썩는 것중에 하나가 소프트버튼 또는 하드버튼으로 입력하는 취소처리, 다이얼로그의 OutSide를 클릭하여 취소하는 경우의 이벤트 처리가 그것일 겁니다.


 그중에서 DatePickerDialog는 기본적으로 Positve버튼과 Cancel버튼이 기본적으로 달려있고, Positive버튼의 이벤트 처리는 다이얼로그 생성자에서 기본적으로 입력을 받습니다.


DatePickerDialog dialog = 
new DatePickerDialog(getActivity(), dateOnDateSetListener, year, month, day);


요런식으로 말이죠..dateOnDateSetListener에서 처리를 합니다. 그럼 취소버튼의 이벤트는 어떨까요.. 이번에 프로그램을 하나 만들면서 취소를 눌렀을 때 아예 날짜를 삭제하는 기능을 넣고 싶었습니다. 그러던중...


 이런저런 많은 방법이 무수히 많았습니다만.. 일단 가장 기초적으로 해결해 보았습니다. 위의 코드에 아래의 코드를 추가합니다.


// 취소버튼을 직접 다시 생성하는 방법으로 취소버튼의 이벤트를 해결
dialog.setButton(DatePickerDialog.BUTTON_NEGATIVE, "취소", new DialogInterface.OnClickListener() {
	@Override
	public void onClick(DialogInterface dialog, int which) {
		((MenuActivity)getActivity()).doSetDate(getTag(), "");
	}
});
// 키리스너를 달아서 취소버튼에 해당하는 KEYCODE값으로 취소버튼이벤트를 감지하여 해결
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
	@Override
	public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
		if (event.getAction() == KeyEvent.KEYCODE_BACK) {
			((MenuActivity)getActivity()).doSetDate(getTag(), "");
		}
		return false;
	}
});


 이제 하나만 남았습니다. OutSide를 클릭하였을 때 이를 검출하여 이벤트를 실행하는 것!!!!

조만간 해당 내용을 포함하여 다시 포스팅하겠습니다.


**** 추가 작성 ****


package com.ubank.ubpos.activity.data.menu;

import java.util.Calendar;

import com.ubank.ubpos.activity.MenuActivity;
import com.ubank.ubpos.common.CommonUtil;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.DatePicker;

public class DlgFrgMenu extends DialogFragment {
	private static final String ARGS_INNER_ID = "inner_id";
	private static final String ARGS_YEAR = "year";
	private static final String ARGS_MONTH = "month";
	private static final String ARGS_DAY = "day";
	public static final int DIALOG_ID_DISCOUNT_START_DATE = 3000001;
	public static final int DIALOG_ID_DISCOUNT_END_DATE = 3000002;
	
	/**
	 * 오늘 날짜를 기준으로 데이트피커다이얼로그를 리턴한다.
	 * 
	 * @param dialogId
	 * 
	 * @return {@link DlgFrgMenu}
	 */
	public static DlgFrgMenu newInstance(int dialogId) {
		DlgFrgMenu dialog = new DlgFrgMenu();
		Bundle bundle = new Bundle();
		bundle.putInt(ARGS_INNER_ID, dialogId);
		dialog.setArguments(bundle);
		return dialog;
	}
	
	/**
	 * param으로 넘어오는 날짜를 기준으로 DatePickerDialog를 리턴한다.
	 * 
	 * @param dialogId
	 * @param strDate 문자열형태 '2013-04-31'
	 * @return {@link DlgFrgMenu}
	 */
	public static DlgFrgMenu newInstance(int dialogId, String strDate) {
		DlgFrgMenu dialog = new DlgFrgMenu();
		Bundle bundle = new Bundle();
		bundle.putInt(ARGS_INNER_ID, dialogId);
		if (strDate != null && strDate.length() == 10) {
			String[] arDate = strDate.split("-");
			bundle.putInt(ARGS_YEAR, Integer.parseInt(arDate[0]));
			bundle.putInt(ARGS_MONTH, Integer.parseInt(arDate[1])-1);
			bundle.putInt(ARGS_DAY, Integer.parseInt(arDate[2]));
		}
		dialog.setArguments(bundle);
		return dialog;
	}
	
	
	@Override
	public Dialog onCreateDialog(Bundle savedInstanceState) {
		
		final int inner_id = getArguments().getInt(ARGS_INNER_ID);
		final int year = getArguments().getInt(ARGS_YEAR, Calendar.getInstance().get(Calendar.YEAR));
		final int month = getArguments().getInt(ARGS_MONTH, Calendar.getInstance().get(Calendar.MONDAY));
		final int day = getArguments().getInt(ARGS_DAY, Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
		
		switch (inner_id) {
		
		case DIALOG_ID_DISCOUNT_START_DATE:
		case DIALOG_ID_DISCOUNT_END_DATE:
			return new DialogDatePickerDialog(getActivity(), dateOnDateSetListener, year, month, day);
		}
		return null;
	}
	
	private class DialogDatePickerDialog extends DatePickerDialog 
		implements DialogInterface.OnKeyListener {

		public DialogDatePickerDialog(Context context, 	OnDateSetListener callBack, 
				int year, int monthOfYear, 	int dayOfMonth) {
			super(context, callBack, year, monthOfYear, dayOfMonth);
		}

		/**
		 * 다이얼로그의 OutSide 클릭이벤트 처리방법
		 */
		@Override
		public boolean dispatchTouchEvent(MotionEvent ev) {
			Rect dialogBounds = new Rect();
			getWindow().getDecorView().getHitRect(dialogBounds);
			if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
				this.dismiss();
				((MenuActivity)getActivity()).doSetDate(getTag(), "");
			}
			return super.dispatchTouchEvent(ev);
		}

		/**
		 * 하드웨어 뒤로가기 키를 처리하는 방법
		 */
		@Override
		public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
			if (event.getAction() == KeyEvent.KEYCODE_BACK) {
				((MenuActivity)getActivity()).doSetDate(getTag(), "");
			}
			return false;
		}

		/**
		 * 뒤로가기 버튼 이벤트 처리방법
		 */
		@Override
		public void onBackPressed() {
			((MenuActivity)getActivity()).doSetDate(getTag(), "");
			super.onBackPressed();
		}
		
		
	}
	
	/**
	 * 날짜선택다이얼로그에서 '설정'을 눌렀을 때의 이벤트 처리방법
	 */
	private DatePickerDialog.OnDateSetListener dateOnDateSetListener = new DatePickerDialog.OnDateSetListener() {
		@Override
		public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
			String strDate = CommonUtil.dfSybolsFour.format(year)
					+ "-" + CommonUtil.dfSybolsTwo.format(monthOfYear+1)
					+ "-" + CommonUtil.dfSybolsTwo.format(dayOfMonth);
			((MenuActivity)getActivity()).doSetDate(getTag(), strDate);
		}
	};
}
반응형