728x90
다이얼로그에서 정보를 받아 리사이클러뷰 아이템을 추가하는 기능을 만듦
DialogFragment
class DialogFragment : DialogFragment() {
private lateinit var binding: FragmentDialogBinding
private var contactDataListener: ContactDataListener? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentDialogBinding.inflate(inflater)
return binding.root
}
override fun onResume() {
//디바이스 가로 사이즈의 90% 설정
val windowManager =
requireContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager
val display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
val params: ViewGroup.LayoutParams? = dialog?.window?.attributes
val deviceWidth = size.x
params?.width = (deviceWidth * 0.9).toInt()
dialog?.window?.attributes = params as LayoutParams
super.onResume()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(binding) {
checkPhoneNumber(etContact, ContactInputLayout)
check(etName, NameInputLayout)
check(etAddress, AddressInputLayout)
spinner.adapter = context?.let { ArrayAdapter.createFromResource(it,R.array.area,android.R.layout.simple_list_item_1) }
val area = when(spinner.selectedItemPosition){
0-> SEOUL
1-> BUSAN
2-> DAEJEON
3-> DAEGU
4-> INCHEON
5-> GWANGJOO
6-> ULSAN
else-> SEOUL
}
btnAdd.setOnClickListener {
val nameEmpty = etName.text!!.isEmpty()
val addressEmpty = etAddress.text!!.isEmpty()
val nameBlank = etName.text!!.isBlank()
val addressBlank = etAddress.text!!.isBlank()
val contactEmpty = etContact.text!!.isEmpty()
//빈 값 있는지 체크
if (nameEmpty || contactEmpty || addressEmpty || !checkNumberLength(
etContact
) || nameBlank || addressBlank || NameInputLayout.error != null || ContactInputLayout.error != null || AddressInputLayout.error != null
) {
if (nameEmpty || nameBlank || NameInputLayout.error != null) NameInputLayout.error =
getString(R.string.Name_error_message) else NameInputLayout.error = null
if (contactEmpty || !checkNumberLength(etContact) || ContactInputLayout.error != null) ContactInputLayout.error =
getString(R.string.Contact_error_message) else ContactInputLayout.error =
null
if (addressEmpty || addressBlank || AddressInputLayout.error != null) AddressInputLayout.error =
getString(R.string.Address_error_message) else AddressInputLayout.error =
null
return@setOnClickListener
} else {
val item = ContactItems.Contents(
etName.text.toString(),
etContact.text.toString(),
etAddress.text.toString(),
area, R.drawable.main_symbol
)
//리스너 호출
contactDataListener?.onContactDataAdded(item)
dialog?.dismiss()
}
}
btnCancel.setOnClickListener {
dialog?.dismiss()
}
}
}
//전화번호 유효성 체크
private fun checkPhoneNumber(editText: EditText, layout: TextInputLayout) {
editText.addTextChangedListener(PhoneNumberFormattingTextWatcher())
editText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (editText.text.isEmpty() || editText.text.isBlank() || editText.text.contains(" ")) layout.error =
getString(R.string.Contact_error_message)
else if (editText.text[0] != '0' && editText.text[0] != '1') layout.error =
getString(R.string.Contact_error_message)
else if (!editText.text.contains("-")) layout.error =
getString(R.string.Contact_error_message)
else layout.error = null
}
override fun afterTextChanged(s: Editable?) {
}
})
}
//시작 번호가 0일때, 1일때 자리수 체크
private fun checkNumberLength(editText: EditText): Boolean {
var state = false
if (editText.text[0] == '0') {
if (editText.text.length == 12) state = true
} else if (editText.text[0] == '1') {
if (editText.text.length == 9 && editText.text.contains("-")) state = true
}
return state
}
//병원명, 주소 유효성 체크
private fun check(editText: EditText, layout: TextInputLayout) {
editText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (editText.text.isEmpty() || editText.text.isBlank() || editText.text.contains(" ")) {
layout.error = "${editText.hint}${getString(R.string.check_footer)}"
} else {
layout.error = null
}
}
override fun afterTextChanged(s: Editable?) {
}
})
}
//리스너 연결
fun setContactDataListener(listener: ContactDataListener) {
contactDataListener = listener
}
}
interface ContactDataListener {
fun onContactDataAdded(item: ContactItems.Contents)
}
ContactFragment
class ContactFragment : Fragment(), ContactDataListener {
private val binding by lazy { FragmentContactBinding.inflate(layoutInflater) }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initRecyclerView()
binding.btnAdd.setOnClickListener {
val dialogFragment = DialogFragment()
dialogFragment.setContactDataListener(this) //리스너 연결
dialogFragment.show(requireActivity().supportFragmentManager, "AddContactDialog")
initToolbarLogo()
}
}
private fun initToolbarLogo() {
binding.recyclerViewContact.initToolbarLogoWithScroll()
}
private fun RecyclerView.initToolbarLogoWithScroll() {
val fadeInAnim = AnimationUtils.loadAnimation(context, R.anim.fade_in)
val logo = binding.ivToolbarLogo
setOnScrollChangeListener { _, _, _, _, _ ->
if (canScrollVertically(-1) && logo.visibility == View.GONE) {
logo.apply {
startAnimation(fadeInAnim)
visibility = View.VISIBLE
}
}
if (!canScrollVertically(-1)) {
logo.apply {
clearAnimation()
visibility = View.GONE
}
}
}
}
private fun initRecyclerView() {
with(binding.recyclerViewContact) {
adapter = ContactListAdapter(ContactItemManager.sortWithHeader())
layoutManager = LinearLayoutManager(context)
}
}
override fun onContactDataAdded(item: ContactItems.Contents) {
//contactItems에 item 추가
ContactItemManager.contactItems.add(item)
//정렬된 list adapter에 연결
binding.recyclerViewContact.adapter = ContactListAdapter(ContactItemManager.sortWithHeader())
binding.recyclerViewContact.adapter?.notifyDataSetChanged()
}
}
2일차 트러블슈팅
아이템을 추가 했을때, 지역별로 추가를 하려고 하는데, item에 add를 하는 방식이라서 맨밑에 추가가 되는 문제가 있었는데, ContactListAdapter의 items에 item을 추가하는 삽질을 계속함.. 데이터를 관리하는 ContactItemManager에있는 contactItems에 추가를 해서 정렬을 하고 아이템을 추가해서 해결함