구현할 내용
- 편집 버튼 클릭시 리사이클러뷰에 띄워진 firebase 정보를 다중 선택
- 이에 따른 상단 버튼의 기능 변화 (취소, 삭제)
- 삭제 버튼 클릭시 firebase storage, DB에서 데이터 삭제
- 6. firebase storage에 이미지 업로드, 7. firebase에서 이미지 불러오기 에서 코드 수정
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_manage)
addbtn = findViewById(R.id.button1)
editbtn = findViewById(R.id.button2)
...
editbtn.setOnClickListener{
toggleMultiSelect()
}
...
}
ㄴ 편집 버튼 클릭시 OnClinckLinstener 실행하여 버튼의 text를 변경하고, imageAdapter를 실행
private fun toggleMultiSelect() {
isMultiSelect = !isMultiSelect
if (isMultiSelect) {
addbtn.text = "취소"
editbtn.text = "삭제"
} else {
addbtn.text = "추가"
editbtn.text = "편집"
}
imageAdapter.toggleMultiSelect()
}
ㄴ 이때, 어댑터는 private lateinit var imageAdapter: ImageAdapter
로 초기화 되어 있어야 한다.
class ImageAdapter(private val items: ArrayList<String>) : RecyclerView.Adapter<ImageAdapter.ViewHolder>() {
private var isMultiSelect = false
private val selectedItems = mutableListOf<String>()
fun toggleMultiSelect() {
isMultiSelect = !isMultiSelect
if (isMultiSelect) {
notifyDataSetChanged()
selectedItems.clear()
} else {
deleteSelectedItems()
}
}
// 아래에 이어서
ㄴ toggleMultiSelect가 전환됨에 따라 선택되는 item의 배경색을 바꿔주기 위해 위와 같은 함수를 작성
private fun deleteSelectedItems() {
val storageRef = FirebaseStorage.getInstance().reference
val databaseRef = Firebase.database.getReference("ocr_results")
// 선택된 이미지들에 대해 firebase storage와 DB에서 삭제
selectedItems.forEach { imageUrl ->
// 파일 경로에서 파일 이름만 추출
val filename = imageUrl.substringAfterLast("%2F")
.substringBeforeLast("?")
Log.d("ImageAdapter", filename)
// firebase storage에서 해당 이미지 삭제
storageRef.child("images/$filename").delete()
// firebase DB에서 해당 이미지 OCR 결과 삭제
databaseRef.orderByChild("image_url").equalTo("/images/$filename").addListenerForSingleValueEvent(object :
ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (snapshot in dataSnapshot.children) {
snapshot.ref.removeValue()
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("ImageAdapter", "onCancelled: ${databaseError.toException()}")
}
})
}
// 선택된 아이템 초기화
selectedItems.clear()
isMultiSelect = false
// 어댑터 갱신
notifyDataSetChanged()
}
// 아래에 이어서
ㄴ 파일명을 이용하여 storage와 DB에서 데이터를 삭제. 이때 파일 이름이 잘못 지정되는 오류를 반복적으로 겪어 val filename = imageUrl.substringAfterLast("%2F").substringBeforeLast("?")
를 이용하여 필요한 부분만 잘라내는 작업을 하였다.
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val imageView: ImageView = itemView.findViewById(R.id.img)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.giftlist, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val imageUrl = items[position]
Glide.with(holder.imageView.context).load(imageUrl).into(holder.imageView)
if (isMultiSelect) {
val isSelected = selectedItems.contains(imageUrl)
holder.itemView.setBackgroundColor(
if (isSelected) {
ContextCompat.getColor(holder.itemView.context, R.color.selectpink)
} else {
Color.TRANSPARENT
}
)
holder.itemView.setOnClickListener {
if (isSelected) {
selectedItems.remove(imageUrl)
} else {
selectedItems.add(imageUrl)
}
notifyItemChanged(position)
}
} else {
holder.itemView.setBackgroundColor(Color.TRANSPARENT)
holder.itemView.setOnClickListener(null)
}
}
}
ㄴ 그밖에 필요한 부분을 마저 작성한다. ViewHolder를 이용하여 리사이클러뷰를 보이고, Glide
라이브러리를 사용하여 이미지를 불러온다.
다중선택 기능이 활성화된 상태라면 select된 item을 따로 selectedItems 이라는 리스트에 보관해야 앞서 작성한 코드들이 정상적으로 작동할 수 있다.