다이얼로그<Dialog>

SO__OK·2023년 2월 6일
0

View의 기초와 활용

목록 보기
8/14

다이얼로그

사용자가 스마트폰에서 앱을 이용하고 있을 때 다양한 상황을 알리기 위해서 다이얼로그(Dialog)를 이용한다. 애플리케이션에서 다이얼로그는 크게 모달(Modal)과 모달리스(Modaless)로 구분하는데, 모달은 다이얼로그를 닫기 전까지 원래의 창을 사용자가 이용할 수 없으며, 모달리스는 다이얼로그가 화면에 떠 있더라도 사용자가 원래의 창을 계속 이용할 수 있다.

◼︎ 토스트(Toast)

안드로이드에서 이용 빈도가 가장 높은 다이얼로그로 화면 하단에 검정 바탕의 흰색 글이 잠깐 보이다가 사라지는 것을 말한다. 모달리스 형식으로 실행되며 사용자를 방행하지 않는다.

다이얼로그와 같은 UI는 제공되지 않지만, 액티비티 화면 위에 띄울 수 있다는 측면에서 다이얼로그의 일종으로 취급한다.

∙ makeText(Context context, int resId, int duration)
∙ makeText(Context context, CharSequence text, int duration)

토스트는 위의 makeText() 함수를 이용하여 생성한다.
두 번째 매개변수가 토스토로 띄울 메세지로 문자열이나 문자열 리소스를 지정한다.
세 번째 매개변수는 토스토로 보이는 메세지의 유지 시간으로 LENGTH_SHORT 이나 LENGTH_LONG으로 지정한다.

LENGTH_SHORT의 실제시간은 3초이며 LENGTH_LONG은 5초이다.
단, 이 값을 임의의 숫자값으로 지정할 수는 없다.

▶︎ 예시

Toast t = Toast.makeText(this, "종료하려면 한번 더 누르세요", 
Toast.LENGTH_SHORT); t.show();

토스트는 문자열만 잠깐 보였다가 사라지게 할 때 사용하므로 위의 코드처럼 간단하게 구현하는게 일반적이지만, 원한다면 다음의 함수를 이용하여 추가로 설정할 수도 있다.

∙ setDuration(int duration)
∙ setText(int resId)
∙ setView(View view)
∙ setGravity(int gravity, int xOffset, int yOffset)
∙ setMargin(float horizontalMargin, float verticalMargin)

setDuration(), setText() 함수는 문자열과 화면에 보이는 시간을 설정할 수 있으며, setView() 함수는 임의의 뷰를 토스트로 띄울 수 있다. 또한, setGravity(), setMargin() 함수는 토스트가 뜨는 위치를 조정할 수 있다.

◼︎ 알림 창

알림 창은 안드로이드 다이얼로그의 가장 기본이며, 사용자에게 메세지 확인을 강제할 수 있다. 간단한 메세지 출력뿐 아니라 다양한 화면 구성이 가능해서 복잡한 화면도 띄울 수 있다. 안드로이드 라이브러리에서 몇몇 다이얼로그를 제공하는데 이들 모두가 AlertDialog의 서브 클래스이다.

알림 창에는 세 가지 영역이 있다.
맨 윗줄은 타이틀(Tiltle) 영역으로 아이콘 이미지와 문자열이 위치한다.
타이틀 영역 아랫부분은 다이얼로그의 본문에 해당하는 영역으로, 문자열을 비롯하여 다양하게 구성할 수 있다. 창 아래는 버튼 영역이다. 알림 창을 구성할 때 타이틀과 버튼에 대한 정보를 지정하지 않으면 두 영역은 출력되지 않는다.

알림 창은 코드에서 직접 new 연산자로 생성하지 못하고 Builder 클래스로 생성해야 한다.

AlertDialog.Builder builder = new AlertDialog.Builder(this);

위의 코드는 알림 창을 생성하는 코드가 아니라, 알림 창을 만들어 주는 Builder 클래스의 객체를 생성한 것이다. Builder 객체의 여러 setter 메서드를 이용하여 다이얼로그 구성을 설정하면 Builder 객체가 알림 창을 생성해 주는 구조이다.

∙ setIcon(int iconId): 타이틀 영역의 아이콘 지정
∙ setMessage(CharSequence message): 본문을 단순 문자열로 구성
∙ setTitle(CharSequence title): 타이틀 문자열 지정

알림 창에 버튼을 추가하려면 다음 함수를 이용하면 된다.

∙ setPositiveButton(CharSequence text, DialogInterface.OnClickListener listener)
∙ setNegativeButton(CharSequence text, DialogInterface.OnClickListener listener)
∙ setNeutralButton(CharSequence text, DialogInterface.OnClickListener listener)

다이얼로그 화면 하단에 들어가는 버튼은 최대 3개까지 지정할 수 있다.
버튼은 각각 positive button, negative button, neutral button으로 구분한다.
몇 개를 추가할 것인지는 개발자의 마음이지만, 같은 성격의 버튼을 두 개 추가할 수는 없다. 즉, setPositiveButton() 함수를 두번 호출하면 같은 성격의 버튼이 중복되어 하나밖에 안 보이게 된다.

이처럼 버튼을 추가하는 함수를 구분하는 이유는 버튼의 UI 측면이 아니라, 어떤 성격의 버튼인지를 구분하여 버튼 클릭 이벤트 처리를 다르게 하는 데 목적이 있다.

▶︎ 예시

builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle("알림");
builder.setMessage("정말 종료 하시겠습니까?");
builder.setPositiveButton("OK", null);
builder.setNegativeButton("NO", null);

Builder에 설정한 내용대로 알림 창을 생성하려면 create() 함수를 이용하고, 생성된 다이얼로그를 show() 함수를 이용해 화면에 출력한다.

alertDialog=builder.create();
alertDialog.show();

알림 창에서 하단의 버튼이 눌리거나 스마트폰 뒤로가기 버튼, 알림 창 밖의 화면을 터치했을 때, 이렇게 세 가지 경우에 알림 창이 닫힌다. 그런데 때에 따라 뒤로가기 버튼을 눌렀을 때 다이얼로그 창이 닫히지 않게 하려면 setCancelable() 함수를 이용한다.

setCancelable(boolean cancelable) 

Builder 클래스의 함수로 이 함수의 값을 false로 지정하면 뒤로가기 버튼에 의해 다이얼로그 창이 닫히는 것을 막을 수 있다. 또한 창 밖을 터치해도 닫히지 않는다.

setCanceledOnTouchOutside(boolean cancel)

위의 함수는 다이얼로그 창밖을 터치했을 때 다이얼로그가 닫히는지에 대한 설정이다.

사용자가 다이얼로그 창 하단의 버튼을 누르면 기본적으로 창이 닫힌다.
하지만 닫히는 순간 추가 이벤트 처리가 필요한 경우도 있다.
다이얼로그 이벤트 처리는 setPositiveButton()과 setNegativeButton() 함수의 두 번째 매개변수에 이벤트 핸들러 클래스를 등록해주면 된다.

builder.setPositiveButton("OK", dialogListener);

setPositiveButton() 함수의 두 번째 매개변수로 dialogListener를 지정하였다.
이 객체는 개발자가 이벤트 처리를 위해 DialogInterface.OnClickListener를 구현한 클래스이다. 이 객체의 onClick() 함수가 이벤트 발생 시 자동으로 호출된다.

DialogInterface.OnClickListener dialogListener=new DialogInterface.OnClickListener() {
   @Override
   public void onClick(DialogInterface dialog, int which) {
           //...
   }
};

onClick() 함수의 첫 번째 매개변수가 이벤트가 발생한 다이얼로그 객체이고, 두 번째 매개변수는 버튼의 종류이다.

◼︎ 목록

목록 형식의 다이얼로그를 띄워야 하는 경우에도 AlertDialg에서 기본으로 제공해 준다.

∙ setItems(int itemsId, DialogInterface.OnClickListener listener)
∙ setItems(CharSequence[] items, DialogInterface.OnClickListener listener)

두 함수 모두 목록을 구성하는데, 첫 번째 함수는 목록을 구성하기 위한 문자열을 배열 리소스로 만들어 사용하고, 두 번째 함수는 코드에서 직접 배열을 만들어 배열을 매개변수로 지정하여 사용한다. 목록 다이얼로그 내에서의 사용자 항목 선택 이벤트는 setItems() 함수의 두 번째 매개변수를 이용하여 구현할 수 있다.

builder.setItems(R.array.dialog_array, dialogListener);

setItem() 함수를 이용하여 목록 다이얼로그를 만들면서 두 번째 매개변수로 항목 선택 이벤트 핸들러 객체를 등록하였다.

DialogInterface.OnClickListener dialogListener=new DialogInterface.OnClickListener() {
	@Override
	public void onClick(DialogInterface dialog, int which) {
	}
};

항목 선택 이벤트가 발생했을 때 호출되는 onClick() 함수의 두 번째 매개변수는 선택한 항목의 인덱스 값이다.

∙ setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems,
				      DialogInterface.OnMultiChoiceClickListener listener)
∙ setMultiChoiceItmes(int itemsId, boolean[] checkedItems,
					  DialogInterface.OnMultiChoiceClickListener listener)

AlertDialog를 이용하여 목록 다이얼로그를 만들 때 각 항목 옆에 체크박스가 나와야 할 경우를 위해 위의 함수를 제공한다. 첫 번째 매개변수로 항목 구성을 위한 배열 값이나 배열 리소스를 지정할 수 있으며, 두 번째 매개변수는 선택되어 있어야 할 체크박스의 체크 상태 값이다. 세 번째 매개변수는 항목 선택 이벤트 핸들러다.

∙ setSingleChoiceItems(CharSequence[] items, int checkedItem, 
					   DialogInterface.OnClickListener listener)
∙ setSingleChoiceItems(int itemsId, int checkedItem,
					   DialogInterface.OnClickListener listener)

위의 함수를 사용하면 항목 옆에 라디오버튼을 나타 낼 수 있으며, 두 번째 매개변수가 초기 선택 항목의 인덱스 값이다.

builder.setSingleChoiceItems(R.array.dialog_array, 0, dialogListener);

배열 정보로 라디오버튼이 나오는 목록 다이얼로그를 띄우는 코드이다. 두 번째 매개변수를 0으로 지정하였으므로 처음 다이얼로그가 열릴 때 첫 번째 라디오버튼이 체크된 상태로 열린다.

◼︎ 날짜 선택

DatePickerDialog dateDialog=new DatePickerDialog(this, null, year, month, day);

두 번째 매개변수는 사용자가 날짜를 선택할 때 발생하는 이벤트 처리 핸들러이며, 이후 숫자 3개가 다이얼로그에서 기본으로 보여야할 날짜 연, 월, 일이다.

   DatePickerDialog dateDialog = new DatePickerDialog(this,
                    new DatePickerDialog.OnDateSetListener(){
   @Override 
    public void onDateSet(DatePicker view, int year, int monthOfYear,
                                              int datOfMonth){
          }
}, year, month, day);
           

이벤트가 발생하면 onDateSet() 함수가 호출되어 매개변수로 사용자가 선택한 연, 월, 일을 받을 수 있다.

◼︎ 시간 선택

날짜 선택(DatePickerDialog)와 마찬가지로 사용자가 시간을 선택할 수 있도록 시간 선택도 제공한다.

TimePickerDialog timeDialog=new TimePickerDialog(this, null, hour, minute, true);

위의 코드처럼 매개변수로 시, 분으로 입력하면 초기 시간이 화면에 나온다. 세 번째 매개변수는 24시간 체계로 나타낼지를 설정하는 논릿값인데, 이 값을 true로 설정하면 24시간 체계로, false로 지정하면 12시간 체계로 오전, 오후를 선택할 수 있는 버튼이 나온다.

시간 조정 이벤트는 생성자의 매개변수에 이벤트 핸들러를 등록하여 처리한다.

TimePickerDialog timeDialog=new TimePickerDialog(this, new TimePickerDialog.
OnTimeSetListener() {
	@Override
	public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    }
}, hour,minute,false);	

◼︎ 커스텀 다이얼로그

라이브러리에서 제공하는 화면 외에 개발자가 원하는 임의의 화면을 다이얼로그 창에 띄워야하는 경우 이용하게 된다.

작성 방법은 우선 다이얼로그 화면을 구성하는 레이아웃 XML 파일을 만든다.

LayoutInflater inflater=(LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view=inflater.inflater(R.layout.dialog_custom, null);
builder.setView(view);

먼저 LayoutInflater 클래스를 이용하여 레이아웃 XML 파일을 초기화 한다. 그리고 초기화된 뷰를 Builder의 setView() 함수를 이용하여 AlertDialog의 본문에 지정하면 된다. 결국 커스텀 다이얼로그는 AlertDialog와 구현 방법이 같은데, 단지 개발자가 직접 구성한 뷰를 setView() 함수를 통해 다이얼로그 본문으로 지정하여 구현한다.

✏️ 힘들어.. 진짜 불같은 11월 말~ 1월을 보냈다.. 피자가게는 겨울이 피크니까.. 어쩔 수 없지만 정말 올 해 겨울은 눈도 많이 와서 유독 더 바빴던거 같다.. 나는 이걸로 취업하게 되면 절대 눈오는 날 배달음식 안 시켜먹어야지..
같이 일하는 배달 친구가 넘어지면서 까지 일을하니.. 안에서 일하는 나는 그냥 입꾹닫.. 다이얼로그는 그렇게 어렵고 복잡한 부분이 아니였는데, 이거 하나 작성하는데 한달은 매달린거 같다(자투리 시간에 했으니..) 오늘은 한 개만 더 하고 집가서 쉬련다!

profile
찌끄레기 코딩

0개의 댓글