Android

[안드로이드/메시징] Dialog

gangmini 2023. 4. 10. 22:43
반응형

Dialog

  • 개발자가 필요시 사용자에게 메시지를 전달하는 용도로 사용 
  • 다이얼로그가 나타나 있을 땐 다른 주변 view 사용 못함 ex. 에러창
  • 메세지 전달이나 입력 등의 용도로 커스텀 가능
// 기본 다이얼로그 설정
binding.button.setOnClickListener {
    var dialog = AlertDialog.Builder(this)

    dialog.setTitle("기본 다이얼로그")
    dialog.setMessage("다이얼로그 메세지 입이다") // 표시할 메세지
    dialog.setIcon(R.mipmap.ic_launcher)

    // 버튼 셋팅 가능
    // 리스너를 넣어 버튼 클릭시 동작하도록 코딩 가능 (null 이면 그냥 사라짐)
    dialog.setPositiveButton("Positive"){ dialoginterface, i->
        // dialoginterface : 이 버튼을 가지고 있는 다이얼로그 객체
        // i : 버튼 구분자 이지만 여기선 각각 따로 세팅하므로 구분 필요 x
        binding.textView.text = "Positive 버튼을 누름"
    }
    dialog.setNeutralButton("Neutral", null)
    dialog.setNegativeButton("Negative"){dialoginterface, i->
        // dialoginterface : 이 버튼을 가지고 있는 다이얼로그 객체
        // i : 버튼 구분자 이지만 여기선 각각 따로 세팅하므로 구분 필요 x
        binding.textView.text = "Negative 버튼을 누름"
    }

    dialog.show()

}

// 커스텀 다이얼로그
binding.button2.setOnClickListener {
   // 커스텀 스낵바처럼 기본 다이얼로그에 뷰를 설정
    var dialog = AlertDialog.Builder(this)

    dialog.setTitle("커스텀 다이얼로그")
    dialog.setIcon(R.mipmap.ic_launcher)

    val custom_dialog_binding = CustomDialog2Binding.inflate((layoutInflater))
    val custom_view = custom_dialog_binding.root
    dialog.setView(custom_view)

    dialog.setPositiveButton("Positive"){ dialoginterface, i->
        // 코틀린은 closure 가 지원되는데 여기서 커스텀 뷰의 뷰를 가져다 사용할 수 있음
        binding.textView.text = "${custom_dialog_binding.customEdit1.text}"
        binding.textView.append("${custom_dialog_binding.customEdit2.text}")
    }
    dialog.setNegativeButton("취소", null)

    dialog.show()

}

 

DatePicker / TimePicker

  • 날짜/시간을 선택할 수 있는 다이얼로그
binding.button3.setOnClickListener {
    val calendar = Calendar.getInstance()

    val year = calendar.get(Calendar.YEAR)
    val month = calendar.get(Calendar.MONTH)
    val day = calendar.get(Calendar.DAY_OF_MONTH)

    val listener1 = DatePickerDialog.OnDateSetListener { datePicker, i, i2, i3 ->
        // datePicker : datePicker 객체
        // i : 선택한 년
        // i2 : 선택한 월
        // i3 : 선택한 일
        binding.textView.text = "${i}년 ${i2 + 1}월 ${i3}일" // 월이 0월 부터 시작하므로 +1 해줘야 한
    }

    val picker = DatePickerDialog(this, listener1, year, month, day) // 캘린더 객체를 다이얼로시간에 셋팅해 캘린더 다이얼로그를 만 + 1
    // 리스너에는 ok 버튼을 누르면 반응할 함수를 셋팅

    picker.show()

}

binding.button4.setOnClickListener {
    val calendar = Calendar.getInstance()

    val hour = calendar.get(Calendar.HOUR)
    val minute = calendar.get(Calendar.MINUTE)


    val listener2 = TimePickerDialog.OnTimeSetListener { timePicker, i, i2 ->
        // timePicker : timePicker 객체
        // i : 선택한 시
        // i2 : 선택한 분
        binding.textView.text = "${i}시 ${i2}분"

    }

    val picker = TimePickerDialog(this, listener2, hour, minute, true) // true: 24시간제, false: 12시간제
    // 리스너에는 ok 버튼을 누르면 반응할 함수를 셋팅

    picker.show()

}

List Dialog

  • 다이얼로그에 ListView를 표시
  • 다이얼로그는 버튼을 총 3개까지 배치할 수 있는데 (pos,neg,neu) 그 이상이 필요한 경우 List Dialog 사용
// 기본 리스트 다이얼로그 (다이얼로그에 리트스뷰를 넣어 커스텀 한다고 생각하면 됨)
binding.button.setOnClickListener {
    var dialog = AlertDialog.Builder(this)

    dialog.setTitle("리스트 다이얼로그")
    dialog.setNegativeButton("취소",null)

    dialog.setItems(data1){dialoginterface, i->
        // i : 선택한 항목
        binding.textView.text = "${i}번째 항목 선택"
    }

    dialog.show()

}

// 커스텀 리스트 다이얼로그 (리스트뷰에 어댑터 설정하는 것과 동일)
binding.button2.setOnClickListener {
    val list1 = ArrayList<HashMap<String, Any?>>()
    for(idx in data2.indices) {
        val map = HashMap<String, Any?>()
        map["data2"] = data2[idx]
        map["data3"] = data3[idx]

        list1.add(map)
    }

    val keys = arrayOf("data2","data2")
    val ids = intArrayOf(R.id.custom_img, R.id.custom_text)

    val adapter = SimpleAdapter(this, list1,R.layout.custom_list,keys,ids)

    var dialog = AlertDialog.Builder(this)
    dialog.setTitle("커스텀 다이얼로그")
    dialog.setNegativeButton("취소", null)

    dialog.setAdapter(adapter){dialoginterface, i->
        binding.textView.text = "항목 ${data2[i]}"
    }
    dialog.show()

}

항목 선택 Dialog 

단일 선택 Dialog

  • 라디오 버튼 형태 
  • AlterDialogBuilder의 setSingleChoiceItems 메서드를 통해 구현 
  • AlertDialogBuilder (다이얼로그 객체)에서 listview를 추출하고 checkedItemPosition 프로퍼티를 이용해 현재 선택된 항목을 추출

다중 선택 Dialog

  • 체크박스 형태
  • AlterDialogBuilder의 setMultiChoiceItems 메서드를 통해 구현
  • AlertDialogBuilder (다이얼로그 객체)에서 listview를 추출하고 checkedItemPositions 프로퍼티를 이용해 현재 선택된 항목을 추출 -> 선택 상태가 변경된 항목의 인덱스가 추출 되므로 현재 선택이 되어 있는건지 아님 방금 취소한건지 확인 필요
// 기본 리스트 다이얼로그 (다이얼로그에 리트스뷰를 넣어 커스텀 한다고 생각하면 됨)
binding.button.setOnClickListener {
    var dialog = AlertDialog.Builder(this)

    dialog.setTitle("single choice 다이얼로그")

    dialog.setSingleChoiceItems(data1,3) {dialoginterface, i ->
        // 첫번째 매개변수 : 항목 데이터
        // 첫번째 매개변수 : 처음에 선택되어 있을 데이터 인덱스 번호
        // 첫번째 매개변수 : 리스너
        val t1 = Toast.makeText(this, data1[i],Toast.LENGTH_SHORT)
        t1.show()
    }

    dialog.setNegativeButton("취소",null)
    dialog.setPositiveButton("확인"){dialoginterface, i ->
        val alert = dialoginterface as AlertDialog //형변환
        val idx = alert.listView.checkedItemPosition //다이얼로그 객체에서 리스트뷰 추출, 선택한 항목 추출
        binding.textView.text = "선택된 항목 : ${data1[idx]} 선택"
    }

    dialog.show()
}

// 커스텀 리스트 다이얼로그 (리스트뷰에 어댑터 설정하는 것과 동일)
binding.button2.setOnClickListener {
    var dialog = AlertDialog.Builder(this)

    val boolArray = booleanArrayOf(true,false,false,true,false,false,false,false) // 처음 시작 체크 여부
    dialog.setMultiChoiceItems(data1, boolArray) {dialoginterface, i, b ->
        // i : 변경된 인덱스 정보 (한번에 하나만)
        // b : 변경된 인덱스의 체크 상태 (체크면 ture)
        if(b == true) {
            val t1 = Toast.makeText(this, "${data1[i]}가 체크됨", Toast.LENGTH_SHORT)
            t1.show()
        }
        else{
            val t1 = Toast.makeText(this, "${data1[i]}가 해제됨", Toast.LENGTH_SHORT)
            t1.show()
        }

    }
    dialog.setTitle("다중 선택 다이얼로그")
    dialog.setNegativeButton("취소", null)
    
    // 확인 버튼을 누르면 체크한 항목들을 텍스트뷰에 표시
    dialog.setPositiveButton("확인"){dialoginterface, i ->
        val alert = dialoginterface as AlertDialog //형변환

        binding.textView.text = ""
        val positions = alert.listView.checkedItemPositions // 체크상태 변경된 애들과 그 애들의 현재 체크 상태
        //Log.d("positions", "${positions}") // {항목 인덱스=bool} 형태

        for (i in 0 until positions.size()) {
            var index = positions.keyAt(i) // key깂(항목 index)을 뽑아냄

            if(positions.get(index) == true) {
                binding.textView.append(data1[index])
            }
        }
    }

    dialog.show()

}

 

💡Closure 란 무엇일까? 람다함수의 끝은 어디인가?...

반응형