• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

댓글 ListView BaseAdapter position 버그 질문

23.03.03 20:16 작성 23.03.04 16:37 수정 조회수 479

0

한사람이 게시글을 작성하면 그 아래 여러사람이 댓글을달고 댓글을 쓴 본인만 댓글을 삭제할수 있도록 구현하려고 합니다. 문제는 한 게시글에 여러사람이 댓글을 달았을때 listView의 getView 메서드의 position이 해당 인덱스의 위치를 잘못된 값을 나타냅니다.

Log로 찍어봤을때 해당 댓글들의 키 배열들은 정상적으로 있으나 두 댓글다 position을 찍어봤을때 0을 찍고 있습니다.(제 생각대로는 첫번째 댓글을 찍으면 0, 두번째 댓글을 찍으면 1이 로그에 찍힘) 왜 리스트뷰가 해당 position이 제대로 찍히지 않는 이유가 궁금합니다!

 

해당 코드입니다.

  • 게시글 내부 댓글부분 코드

var commentlist = ArrayList<CommentModel>()
var commentKeyList = ArrayList<String>()
var commentLV = binding.commentLV
var lvAdpater = CommentAdapter(commentlist , commentKeyList , key  )
commentLV.adapter = lvAdpater
val postListener = object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        commentlist.clear()
        commentKeyList.clear()
        for(dataModel in dataSnapshot.children){
            val item = dataModel.getValue(CommentModel::class.java)
            if (item != null) {
                commentlist.add(item)
                commentKeyList.add(dataModel.key.toString())
            }
        }
        lvAdpater.notifyDataSetChanged()
        // ...
    }

    override fun onCancelled(databaseError: DatabaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
    }
}
FBRef.commentRef.child(key).addValueEventListener(postListener)
class CommentAdapter(var list : ArrayList<CommentModel> , var keyList : ArrayList<String>, var key : String): BaseAdapter() {
    var applicantID : String = ""

    override fun getCount(): Int {
        return list.size
    }

    override fun getItem(p0: Int): Any {
        return list[p0]
    }

    override fun getItemId(p0: Int): Long {
        return p0.toLong()
    }

    override fun getView(position: Int, p1: View?, p2: ViewGroup?): View {
        var view = p1
        if(p1 == null){
            view = LayoutInflater.from(p2?.context).inflate(R.layout.comment_item, p2, false)
        }

        val applicant = view?.findViewById<TextView>(R.id.applicant)
        val content = view?.findViewById<TextView>(R.id.contentArea)
        val time = view?.findViewById<TextView>(R.id.timeArea)

        applicant?.text = list[position].applicant
        applicantID = list[position].applicantID
        content?.text = list[position].comment
        time?.text = list[position].time

        var removeBtn  = view!!.findViewById<ImageView>(R.id.removeBtn)
//        var inviteBtn = view!!.findViewById<Button>(R.id.inviteBtn)

        if(FBAuth.getUid().equals(applicantID)){
            removeBtn.isVisible = true
            removeBtn.setOnClickListener {
                var commentKey = keyList[position]
                Log.e("key",keyList.toString())
                Log.e("key", position.toString())

                var dlg = AlertDialog.Builder(view.context)
                dlg.setTitle("댓글을 삭제하겠습니까?")
                dlg.setPositiveButton("확인", DialogInterface.OnClickListener { dialogInterface, i ->
                    FBRef.commentRef.child(key).child(commentKey).removeValue()
                })
                dlg.setNegativeButton("취소",null)
                dlg.show()
            }

        }
        return view!!
    }
}

답변 1

답변을 작성해보세요.

0

안녕하세요

제가 이해하기로는 listview에 item을 클릭하는 이벤트를 달고싶은데 이게 잘 안되신다는 말씀이 맞으신가요?

 

https://www.android--code.com/2020/03/android-kotlin-listview.html

 

위의 링크처럼 이렇게 이벤트 처리를 해도 안되시나요?

잘 안되시면 어떻게 시도하셨는지 과정과 전체 코드를 복사해서 공유해주세요 :)

 

 // List view item click listener
        listView.onItemClickListener = AdapterView.OnItemClickListener {
                parent, view, position, id ->
            val selectedItemText = parent.getItemAtPosition(position)
            textView.text = "Selected : $selectedItemText"
        }
dmsdl261님의 프로필

dmsdl261

질문자

2023.03.04

해결했습니다!! 저는 listview item을 클릭했을때가 아니라 내부의 imageView 버튼을 클릭했을 때 해당 item을 삭제하는 이벤트를 구현하고 본인이 댓글작성자 본인만(지금 로그인 되어있는 아이디와 댓글 작성자의 아이디가 일치할때만) 삭제 버튼을 보이도록 하려고 했습니다. 지금 로그인 되어있는 아이디와 댓글 작성자의 아이디가 일치하는지 검사하는 부분을 분리하고 일치하지 않을시 isVisible을 false로 처리하도록 수정하니 문제가 해결되었습니다!

  • 수정된 코드

class CommentAdapter(var list : ArrayList<CommentModel> , var keyList : ArrayList<String>, var key : String): BaseAdapter() {

    override fun getCount(): Int {
        return list.size
    }

    override fun getItem(p0: Int): Any {
        return list[p0]
    }

    override fun getItemId(p0: Int): Long {
        return p0.toLong()
    }

    override fun getView(position: Int, p1: View?, p2: ViewGroup?): View {
        var view = p1
        if(p1 == null){
            view = LayoutInflater.from(p2?.context).inflate(R.layout.comment_item, p2, false)
        }

        val applicant = view?.findViewById<TextView>(R.id.applicant)
        val content = view?.findViewById<TextView>(R.id.contentArea)
        val time = view?.findViewById<TextView>(R.id.timeArea)

        applicant?.text = list[position].applicant
        content?.text = list[position].comment
        time?.text = list[position].time

        var removeBtn  = view!!.findViewById<ImageView>(R.id.removeBtn)

        if(FBAuth.getUid().equals(list[position].applicantID)) {
            removeBtn.isVisible = true
        }
        else {
            removeBtn.isVisible = false
        }

        removeBtn.setOnClickListener {

            var commentKey = keyList[position]
            var dlg = AlertDialog.Builder(view.context)
            dlg.setTitle("댓글을 삭제하겠습니까?")
            dlg.setPositiveButton("확인", DialogInterface.OnClickListener { dialogInterface, i ->
                FBRef.commentRef.child(key).child(commentKey).removeValue()
            })
            dlg.setNegativeButton("취소",null)
            dlg.show()
        }

        return view!!
    }
}