오늘은 어제 완성시킨 swipe에서 끊임없이 오류가 발생해서 처음에 구현했던 swipe로 다시 되돌렸다.
어제 완성시켰던 swipe는 recyclerview의 item을 오른쪽으로 드래그하면 삭제 버튼이 나오고 버튼을 눌렀을 때 연락처목록에서 데이터가 삭제되는 형식으로 구현했다.
하지만 오늘 다른 코드들과 합치고 추가적으로 swipe를 손을 더 보고 난 후에 다시 작동했을 때 어제 발견되지 않았던 오류들이 생기기 시작했다.
먼저 item하나를 옆으로 밀었을 때 아래에 있는 다른 item도 함께 밀려서 두 개의 item에서 삭제버튼이 출현하게 되는 오류가 발생했다.
다음으로 중간에 있는 item을 밀어 삭제했을 때 다른 item에서는 삭제 버튼이 나타나면 안되는데 계속해서 나타나게 되었다.
그리고 삭제 버튼을 framelayout을 이용해서 가려놨는데 item을 드래그하고 다시 닫고 난 후 삭제 버튼이 있는 곳을 클릭하니 디테일 페이지가 뜨지 않고 바로 item이 삭제되었다.
위의 이유말고도 많은 오류가 생겨 처음에 작성했던 스와이프만으로 item을 삭제하도록 코드를 새로 작성했다. 이때 작성한 코드는 아래와 같다.
class SwipeHelperCallback(private val recyclerViewAdapter: ContactAdapter) :
ItemTouchHelper.Callback() {
private val background = ColorDrawable()
private val clearPaint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) }
// 이동 방향 결정하기
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
// 드래그 방향 : 위, 아래 인식
// 스와이프 방향 : 왼쪽, 오른쪽 인식
// 설정 안 하고 싶으면 0
return makeMovementFlags(0, RIGHT)
}
// 드래그 일어날 때 동작 (롱터치 후 드래그)
override fun xxonMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return true
}
// 스와이프 일어날 때 동작
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
// 스와와이프 끝까지 하면 해당 데이터 삭제하기 -> 스와이프 후 <삭제> 버튼 눌러야 삭제 되도록 변경
if (viewHolder.itemViewType == ConstValues.VIEW_TYPE_TITLE) return //스와이프 했을 때 VIEWTYPE이 TITLE이면 실행되지 않도록 설정
recyclerViewAdapter.removeData(viewHolder.layoutPosition)
}
@SuppressLint("ResourceAsColor")
override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
val itemView = viewHolder.itemView
// val itemHeight = itemView.bottom - itemView.top
val isCanceled = dX == 0f && !isCurrentlyActive
if (isCanceled) {
clearCanvas(
c,
itemView.left + dX,
itemView.top.toFloat(),
itemView.left.toFloat(),
itemView.bottom.toFloat()
)
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
return
}
if (actionState == ACTION_STATE_SWIPE) {
if (viewHolder.itemViewType == ConstValues.VIEW_TYPE_TITLE) return
}
// Draw the red delete background
background.color = Color.parseColor("#FF0000")
background.setBounds(
itemView.left + dX.toInt(),
itemView.top,
itemView.left,
itemView.bottom
)
background.draw(c)
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) {
c?.drawRect(left, top, right, bottom, clearPaint)
}
}
더 추가된 코드는 onChildDraw에서 background의 색을 바꾸는 코드이다. 이 코드는 스와이프를 했을 때 item뒤에 배경의 색을 바꿔준다. 이때 R.color.red 형식으로 코드를 작성했을 떄 제대로 구현이 되지 않아 Color.parseColor를 이용해서 강제로 색상을 변경하도록 만들었다.
그리고 recyclerview에 있는 item에서 VIEW TYPE이 TITLE인 것을 드래그 했을 때 작동하지 않고 LIST인 것을 드래그 했을 때 드래그 될 수 있도록 아래의 코드를 추가했다.
if (actionState == ACTION_STATE_SWIPE) {
if (viewHolder.itemViewType == ConstValues.VIEW_TYPE_TITLE) return
}
이 코드는 item이 클릭이 되거나 스와이프 됐을 때 ( -> actionState == ACTION_STATE_SWIPE ) VEWTYPE을 비교하고 ( viewHolder.itemViewType == ConstValues.VIEW_TYPE_TITLE ) TITLE이면 작동하지 않도록 만들어준다.