강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

양혁진님의 프로필 이미지
양혁진

작성한 질문수

[초급편] 안드로이드 커뮤니티 앱 만들기(Android Kotlin)

북마크 탭 만들기 - 3

북마크 페이지 관련 질문 있습니다

작성

·

391

0

좋은 수업 감사합니다 강사님. 수업을 듣다가 의문점이 들어서 이렇게 질문을 남깁니다.

강사님께서 수업해주신 내용 그대로 코드를 작성했습니다. 그런데 북마크 페이지에서는 북마크를 해제할 수 없던데 혹시 북마크 페이지에서 북마크를 해제하는 코드를 작성하는 방법을 알려주실 수 있으신가요? 코드는 강사님께서 만드신 코드와 동일해서 따로 첨부하지 않았습니다. 

주말에도 귀찮게 만들어 드린 것 같아 죄송합니다. 

답변 3

0

개복치개발자님의 프로필 이미지
개복치개발자
지식공유자

안녕하세요 이 부분이 원인인데요~

private fun getCategoryData(){
        val postListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {

                for (dataModel in dataSnapshot.children){
                    val item = dataModel.getValue(ContentModel::class.java)
                    //3. 전체 컨텐츠 중, 사용자가 북마크한 정보만 보여줌
                    if(bookmarkIdList.contains(dataModel.key.toString())){
                        items.add(item!!)
                        itemKeyList.add(dataModel.key.toString())
                    }
                }
                rvAdapter.notifyDataSetChanged()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        FBRef.category1.addValueEventListener(postListener)
        FBRef.category2.addValueEventListener(postListener)
    }

    private fun getBookmarkData(){

        val postListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                bookmarkIdList.clear()

                for (dataModel in dataSnapshot.children){
                    bookmarkIdList.add(dataModel.key.toString())
                }
                //1. 전체 카테고리에 있는 컨텐츠 데이터들을 다 가져옴
                getCategoryData()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        FBRef.bookmarkRef.child(FBAuth.getUid()).addValueEventListener(postListener)

    }

Firebase에서는 데이터가 변하면 onDataChange가 자동으로 실행되도록 구성되어 있습니다.

때문에, 리스트에 들어있는 데이터에 새로 변경된 데이터가 불러와져서 중복 데이터가 들어가는 형태에요

 

때문에 이미 리스트에 들어있는 값들을 clear해주셔야 하는데요

 북마크를 아래와 같이 하셨던 것 처럼

bookmarkIdList.clear()

 items의 컨텐츠들도 onDataChange 부분에서 clear()를 해주세요 ~

 

양혁진님의 프로필 이미지
양혁진
질문자

감사합니다!!!

0

양혁진님의 프로필 이미지
양혁진
질문자

북마크 페이지에서 북마크가 해지되긴 하는데, 같이 북마크 등록되어있는 요소들이 한 번 더 나옵니다. 제가 수정한 BookmarkRVAdapter 와 BookmarkFragment 코드 첨부하겠습니다.

 

BookmarkRVAdapter

package com.example.mysololife.contentsList

import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.mysololife.R
import com.example.mysololife.utils.FBAuth
import com.example.mysololife.utils.FBRef

class BookmarkRVAdapter(val context : Context,
                       val items:ArrayList<ContentModel>,
                       val keyList : ArrayList<String>,
                       val bookmarkIdList : MutableList<String>)
    : RecyclerView.Adapter<BookmarkRVAdapter.Viewholder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookmarkRVAdapter.Viewholder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.content_rv_item, parent, false)

        Log.d("BookmarkRVAdapter", keyList.toString())
        Log.d("BookmarkRVAdapter", bookmarkIdList.toString())
        return Viewholder(v)
    }

    override fun onBindViewHolder(holder: BookmarkRVAdapter.Viewholder, position: Int) {
        holder.bindItems(items[position], keyList[position])
    }

    override fun getItemCount(): Int {
        return items.size
    }

    inner class Viewholder(itemView : View) : RecyclerView.ViewHolder(itemView){

        fun bindItems(item: ContentModel, key: String){

            itemView.setOnClickListener{
                Toast.makeText(context, item.title, Toast.LENGTH_LONG).show()
                val intent = Intent(context, ContentShowActivity::class.java)
                intent.putExtra("url", item.webUrl)
                itemView.context.startActivity(intent)
            }

            val contentTitle= itemView.findViewById<TextView>(R.id.textArea)
            val imageViewArea = itemView.findViewById<ImageView>(R.id.imageArea)
            val bookmarkArea = itemView.findViewById<ImageView>(R.id.bookmarkArea)

            if(bookmarkIdList.contains(key)){
                bookmarkArea.setImageResource(R.drawable.bookmark_color)
            } else {
                bookmarkArea.setImageResource(R.drawable.bookmark_white)
            }

            bookmarkArea.setOnClickListener {
                Log.d("BookmarkRVAdapter", FBAuth.getUid())
                Toast.makeText(context, key, Toast.LENGTH_LONG).show()

                //북마크 있을때
                if(bookmarkIdList.contains(key)){
                bookmarkIdList.clear()
                    Log.d("BookmarkRVAdapter", keyList.toString())
                    Log.d("BookmarkRVAdapter", bookmarkIdList.toString())

                    FBRef.bookmarkRef
                        .child(FBAuth.getUid())
                        .child(key)
                        .removeValue()
                } else{
                    FBRef.bookmarkRef
                        .child(FBAuth.getUid())
                        .child(key)
                        .setValue(BookmarkModel(true))
                }

                //북마크 없을 때

            }

            contentTitle.text = item.title

            Glide.with(context).load(item.imageUrl).into(imageViewArea)

        }

    }

}

 

BookmarkFragment

package com.example.mysololife.fragments

import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.mysololife.R
import com.example.mysololife.contentsList.BookmarkRVAdapter
import com.example.mysololife.contentsList.ContentModel
import com.example.mysololife.databinding.FragmentBookmarkBinding
import com.example.mysololife.utils.FBAuth
import com.example.mysololife.utils.FBRef
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.ValueEventListener

class BookmarkFragment : Fragment() {

    private lateinit var binding:FragmentBookmarkBinding
    private var TAG = BookmarkFragment::class.java

    val bookmarkIdList = mutableListOf<String>()
    val items = ArrayList<ContentModel>()
    val itemKeyList = ArrayList<String>()

    lateinit var rvAdapter : BookmarkRVAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_bookmark, container, false)

        //2. 사용자가 북마크한 정보를 다 가져옴
        getBookmarkData()

        rvAdapter= BookmarkRVAdapter(requireContext(), items, itemKeyList, bookmarkIdList)

        val rv : RecyclerView = binding.bookmarkRV
        rv.adapter = rvAdapter

        rv.layoutManager = GridLayoutManager(requireContext(), 2)
        binding.homeTap.setOnClickListener {
            it.findNavController().navigate(R.id.action_bookmarkFragment_to_homeFragment)
        }

        binding.tipTap.setOnClickListener {
            it.findNavController().navigate(R.id.action_bookmarkFragment_to_tipFragment)
        }

        binding.talkTap.setOnClickListener {
            it.findNavController().navigate(R.id.action_bookmarkFragment_to_talkFragment)
        }

        binding.storeTap.setOnClickListener {
            it.findNavController().navigate(R.id.action_bookmarkFragment_to_storeFragment)
        }
        // Inflate the layout for this fragment
        return binding.root
    }

    private fun getCategoryData(){
        val postListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {

                for (dataModel in dataSnapshot.children){
                    val item = dataModel.getValue(ContentModel::class.java)
                    //3. 전체 컨텐츠 중, 사용자가 북마크한 정보만 보여줌
                    if(bookmarkIdList.contains(dataModel.key.toString())){
                        items.add(item!!)
                        itemKeyList.add(dataModel.key.toString())
                    }
                }
                rvAdapter.notifyDataSetChanged()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        FBRef.category1.addValueEventListener(postListener)
        FBRef.category2.addValueEventListener(postListener)
    }

    private fun getBookmarkData(){

        val postListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                bookmarkIdList.clear()

                for (dataModel in dataSnapshot.children){
                    bookmarkIdList.add(dataModel.key.toString())
                }
                //1. 전체 카테고리에 있는 컨텐츠 데이터들을 다 가져옴
                getCategoryData()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        FBRef.bookmarkRef.child(FBAuth.getUid()).addValueEventListener(postListener)

    }


}

현재 북마크 등록 상황

 

=> title1의 북마크 부분을 눌렀을 경우

 

0

개복치개발자님의 프로필 이미지
개복치개발자
지식공유자

안녕하세요 혁진님~

질문주셔도 전혀 귀찮지 않습니다. 궁금하시면 언제든지 문의주세요.

 

우선 카테고리 페이지에서 북마크를 해지하는 기능이 구현되어 있습니다.

key 값이라고 해서 문서 아이디를 기반으로 북마크를 설치하고 해지하는 방식인데

북마크 페이지에서도 firebase에서 받아온 key값을 바탕으로 똑같이 구현해주시면 됩니다.

 

아마 시도해보시면 금방 하실 수 있으실거에요.

 

해보시고 어려우시면 어떻게 시도하셨는지 코드와 함께 공유해주세요 :)

 

양혁진님의 프로필 이미지
양혁진

작성한 질문수

질문하기