안녕하세요. 이어서 이번에는 연락처를 삭제하는 기능을 구현해보려고 합니다.
연락처의 권한 획득과 연락처를 불러오기 위한 글은 아래의 게시글을 확인해주세요.
[Android] 안드로이드 Permission(권한) 예제 - 연락처/주소록 만들기 1
안녕하세요. 이번에는 DangerousPermission 중 READ_CONTACTS와 WRITE_CONTACTS의 권한을 획득하여 주소록 앱을 만들어보고자 합니다. AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> 먼저 AndroidM..
jdroid.tistory.com
연락처 추가 및 수정 게시글은 아래에서 확인해주세요.
[Android] 안드로이드 Permission(권한) 예제 - 연락처/주소록 만들기 (연락처 추가/수정)
안녕하세요. 지난번에 이어 이번에는 연락처를 추가/수정하는 기능을 구현해보려고 합니다. 지난 글과 이어지기 때문에 연락처의 권한 획득과 연락처를 불러오기 글을 먼저 확인해주세요. 먼저
jdroid.tistory.com
지난 게시글들과 이어서 진행되기 때문에 앞선 게시글들을 보고 와주세요.
이제 연락처 삭제 방법에 대해 알아보겠습니다.
view_contacts_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout ... >
<LinearLayout ... >
<androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:clickable="false"
android:minWidth="0dp"
android:minHeight="0dp" />
<TextView ... />
<TextView ... />
</LinearLayout>
<View ... />
</androidx.constraintlayout.widget.ConstraintLayout>
연락처 목록의 디자인인 view_contacts_list.xml에 삭제를 하기 위한 CheckBox를 추가해 줍니다.
ContactsAdapter.kt
class ContactsAdapter(private val contactsList: ArrayList<ContactsData>, private val onItemClickListener: OnItemClickListener, private val checkedList: MutableSet<Int>) : RecyclerView.Adapter<ContactsAdapter.ViewHolder>() {
interface OnItemClickListener {
fun onItemClickListener(position: Int)
fun onItemLongClickListener(position: Int)
}
private var isDeleteMode = false
private var longPosition = -1
...
fun setDeleteMode(deleteMode: Boolean) {
isDeleteMode = deleteMode
notifyItemRangeChanged(0, itemCount)
}
inner class ViewHolder(private val binding: ViewContactsListBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind() {
binding.txtName.text = contactsList[adapterPosition].name
binding.txtPhoneNumber.text = PhoneNumberUtils.formatNumber(contactsList[adapterPosition].number, Locale.getDefault().country)
binding.checkbox.isVisible = isDeleteMode
if (isDeleteMode) {
binding.checkbox.isChecked = checkedList.any { adapterPosition == it }
} else {
checkedList.clear()
binding.checkbox.isChecked = false
longPosition = -1
}
if (longPosition == adapterPosition) {
binding.checkbox.isChecked = true
checkedList.add(adapterPosition)
}
itemView.setOnClickListener {
binding.checkbox.performClick()
if (binding.checkbox.isChecked) {
checkedList.add(adapterPosition)
} else {
checkedList.remove(adapterPosition)
}
}
itemView.setOnLongClickListener {
checkedList.add(adapterPosition)
onItemClickListener.onItemLongClickListener(adapterPosition)
return@setOnLongClickListener false
}
}
}
}
isDeleteMode, longPosition : isDeleteMode와 longPosition 전역 변수를 생성합니다. 이 변수들은 삭제 모드인지 확인하는 Boolean값과 롱 클릭 시 클릭된 연락처는 체크를 할 수 있도록 하기 위한 변수입니다.
OnItemClickListener : 기존에 만들어 놨던 OnItemClickListener Interface에 onItemLongClickListener를 추가해줍니다. itemView가 롱 클릭됐을 경우 이 메서드로 callback을 전달하게 됩니다.
setDeleteMode() : 이 메서드는 MainActivity에서 삭제모드를 설정/해제할 때 사용되는 메서드입니다.
binding.checkbox.isVisible = isDeleteMode : 삭제 모드일 경우 체크박스를 visible 처리하고 삭제 모드가 아닐 경우라면 gone처리를 해주게 됩니다.
if ~ else : 삭제 모드일 때는 checkedList에 포지션이 속할 경우 checkBox를 checked 해주게 됩니다. 삭제 모드가 아닐 경우에는 checkedList를 clear 해주고 checkBox의 checked를 해제해 줍니다.
setOnClickListener : 기존에는 클릭했을 경우 interface callback만 실행시켰었는데 삭제 모드일 경우에 checkBox를 체크해주고 checkedList에 checked라면 add 아니라면 remove 해주며, 삭제 모드가 아닐 경우에만 callback을 전달합니다.
setOnLongClickListener : itemView를 롱 클릭했을 경우 해당 아이템을 checkedList에 추가해주고, interface callback을 전달합니다.
MainActivity.kt
class MainActivity : AppCompatActivity(), View.OnClickListener {
...
private var checkedList: MutableSet<Int> = mutableSetOf()
private var isDeleteMode = false
private val onItemClickListener = object : ContactsAdapter.OnItemClickListener {
...
override fun onItemLongClickListener(position: Int) {
isDeleteMode = true
setModeUI()
}
}
...
override fun onClick(v: View?) {
when (v) {
...
binding.includeTitle.btnDelete -> {
checkedList.sortedDescending().forEach {
setDeleteContacts(contactsList[it], it)
}
Toast.makeText(this, "연락처 삭제가 완료되었습니다.", Toast.LENGTH_SHORT).show()
isDeleteMode = false
setModeUI()
}
}
}
override fun onBackPressed() {
if (isDeleteMode) {
isDeleteMode = false
setModeUI()
} else {
super.onBackPressed()
}
}
...
private fun initListener() {
...
binding.includeTitle.btnDelete.setOnClickListener(this)
}
private fun setModeUI() {
binding.includeTitle.btnDelete.isVisible = isDeleteMode
binding.btnAddContacts.isVisible = !isDeleteMode
contactsAdapter?.setDeleteMode(isDeleteMode)
}
private fun setDeleteContacts(contacts: ContactsData, index: Int) {
contentResolver.delete(ContactsContract.RawContacts.CONTENT_URI, "${ContactsContract.RawContacts.CONTACT_ID}=?", arrayOf(contacts.contactsId.toString()))
contactsList.removeAt(index)
contactsAdapter?.notifyItemRemoved(index)
}
}
checkedList, isDeleteMode : checkedList는 check 된 Item의 position을 저장하고, isDeleteMode는 Adapter와 동일하게 삭제 모드를 뜻합니다.
onClick() : onClickListener에 TitleBar의 btnDelete를 추가해줍니다. TitleBar의 btnDelete를 클릭할 경우 checkedList의 아이템들을 setDeleteContact로 넘겨 연락처를 삭제하고 삭제가 완료되면 삭제 모드를 해제합니다.
onBackPressed() : 삭제 모드일 때 사용자가 back버튼 동작을 하였을 때 삭제 모드를 해제하고 삭제 모드가 아니라면 onBackPressd 동작을 하게 됩니다.
initListener() : 이 메서드에서 TitleBar의 btnDelete의 리스너를 등록합니다.
setModeUI() : 삭제 모드라면 타이틀바의 삭제버튼을 visible처리해주고, btnAddContacts버튼을 gone처리, 아까 생성했던 contactsAdapter의 setDeleteMode에 삭제모드 여부를 전달합니다.
setDeleteContacts() : 이 메서드는 연락처를 실제로 삭제하는 부분의 메서드입니다. ContactsData에 저장되어있던 연락처의 ID를 이용하여 이 ID를 contentResolver.delete에 전달하여 삭제합니다. 삭제된 연락처는 contactsList에서 삭제하고 RecyclerView의 해당 Position에 Remove 했다고 알려줍니다.
그럼 지금까지 만든 내용의 결과를 보겠습니다.
이번에는 연락처의 삭제하는 방법에 대해 알아보았습니다.
연락처의 소스코드는 아래의 제 Github에서 보실 수 있습니다.
GitHub - won-droid/function
Contribute to won-droid/function development by creating an account on GitHub.
github.com
문제가 있거나 이해가 되지 않는 부분이 있으시면 댓글을 남겨주시면 답변드리겠습니다!
'Android > Libraries' 카테고리의 다른 글
[Android] 안드로이드 Permission(권한) 예제 - 연락처/주소록 만들기 (연락처 추가/수정) (0) | 2022.08.07 |
---|---|
[Android] 안드로이드 Permission(권한) 예제 - 연락처/주소록 만들기 (권한 획득, 연락처 불러오기) (0) | 2022.07.24 |
[Android] Parcelable 생성 Parcelize로 편하게 생성하기(with Serializable) (0) | 2022.07.24 |
[Android] 안드로이드 Permission(권한) 종류 및 권한 획득 예제(지문인증 / 생체 인증) (0) | 2022.07.11 |
[Android] 안드로이드12 대응 SplashScreen(스플래시 스크린) 만들기 (1) | 2022.07.09 |