본문 바로가기

Android Project

[Android/Kotlin] 커뮤니티앱(6) - 북마크탭 만들기

북마크탭에 구현해볼것은 내가 북마크한 컨텐츠만 북마크탭에 나타나도록 해볼것이다 

 

현재 컨텐츠에 대한 정보와 북마크에 대한 정보들도 알고있기때문에 그걸활용해서 

북마크탭을 눌렀을때 모든 컨텐츠에 대한 데이터를 다 가져오고 북마크데이터를 가져와서 북마크에 있는 id값을 가지고 있는 애들만 노출시키도록 할것이다

 

BookmarkFragment로 가서 아래순서대로 코드를 짜줄것이다

1. 전체 카테고리에있는 컨텐츠 데이터들을 다 가져온다

2. 사용자가 북마크한 정보를 다 가져온다

3. 전체 컨텐츠 중에서, 사용자가 북마크한 정보만 보여준다 

 

1번을 실행시켜줄려면 DatabaseReference를 선언해서 가져와야하는데 매번 선언하기가 귀찮기때문에

좀더 간단하게 해주기위해 FBRef.kt 파일에가서 해당 코드를 추가시켜준다

package com.example.mysololife.utils

class FBRef {

    companion object{
        private val database = Firebase.database

        // 컨텐츠 데이터 가져오기
        val category1 = database.getReference("contents")
        val category2 = database.getReference("contents2")
        val category3 = database.getReference("contents3")
        val category4 = database.getReference("contents4")
        val category5 = database.getReference("contents5")
        val category6 = database.getReference("contents6")
        val category7 = database.getReference("contents7")
        val category8 = database.getReference("contents8")

       
        val bookmarkRef = database.getReference("bookmark_list")

    }
}

FBRef.kt

 

BookmarkFragment로 가서 getCategoryData함수를 만들어서 데이터를 가져오는 코드를 작성해준다

전체데이터를 받아와야되기때문에 category1부터 category8까지 다 받아온다

package com.example.mysololife.fragments

class BookmarkFragment : Fragment() {

    private lateinit var binding : FragmentBookmarkBinding

    private val TAG = BookmarkFragment::class.java.simpleName

    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)

        // 1. 전체 카테고리에 있는 컨텐츠 데이터들을 다 가져옴
        getCategoryData()

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

        // 3. 전체 컨텐츠 중에서, 사용자가 북마크한 정보만 가져옴


        ...
    }


	// 1번 실행시키는 함수
    private fun getCategoryData(){

        // 데이터 가져오기
        val postListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {

                for (dataModel in dataSnapshot.children){

                    Log.d(TAG,dataModel.toString())

                }
            }

            override fun onCancelled(databaseError: DatabaseError) {
                // Getting Post failed, log a message
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        // 전체 데이터 받아옴
        FBRef.category1.addValueEventListener(postListener)
        FBRef.category2.addValueEventListener(postListener)
        FBRef.category3.addValueEventListener(postListener)
        FBRef.category4.addValueEventListener(postListener)
        FBRef.category5.addValueEventListener(postListener)
        FBRef.category6.addValueEventListener(postListener)
        FBRef.category7.addValueEventListener(postListener)
        FBRef.category8.addValueEventListener(postListener)

    }


}

BookmarkFragment.kt

로그를 사용해서 찍어보면 전체 데이터들이 잘 가져와가진것을 확인할수있다 

 

 

이제 2번인 사용자가 북마크한 정보를 가져와볼것이다

getBookmarkData()함수를 만들어서 북마크 데이터를 가져오는 코드를 짜주고 함수를 실행시켜준다 

package com.example.mysololife.fragments

class BookmarkFragment : Fragment() {

    private lateinit var binding : FragmentBookmarkBinding

    private val TAG = BookmarkFragment::class.java.simpleName

    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)

        // 1. 전체 카테고리에 있는 컨텐츠 데이터들을 다 가져옴
        getCategoryData()

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

        // 3. 전체 컨텐츠 중에서, 사용자가 북마크한 정보만 가져옴



        ...
    }

        ...


    // 북마크 데이터 가져오기
    private fun getBookmarkData(){

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

                for (dataModel in dataSnapshot.children){

                    Log.e(TAG, dataModel.toString())
                }

            }

            override fun onCancelled(databaseError: DatabaseError) {
                // Getting Post failed, log a message
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        // 북마크 데이터받아옴
        FBRef.bookmarkRef.child(FBAuth.getUid()).addValueEventListener(postListener)

    }



}

BookmarkFragment.kt

 

이렇게하고 로그를 찍어서확인해보면 내가 북마크한것이 잘 찍히는것을 볼수있다 

 

이제 3번에 해당하는 코드를 짜줄건데 

1번,2번 데이터를 다 어뎁터에 넘겨줘서 어뎁터에서 처리를 해주면 될것이다

따라서 BookmarkRVAdapter라는 새로운 어뎁터를 만들어주는데, 원래 만들어놨던 ContentRVAdapter랑 로직이 비슷해서 복붙해서 조금만 수정해주기만 할것이다

package com.example.mysololife.contentsList

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("ContentRVAdapter", keyList.toString())
        Log.d("ContentRVAdapter", 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 {
                val intent = Intent(context, ContentShowActivity::class.java)
                //데이터도 함께 넘겨줌
                intent.putExtra("url", item.webUrl)
                itemView.context.startActivity(intent)

            }

            // content_rv_item에서 텍스트, 이미지,북마크를 찾아옴(연결)
            val contentTitle = itemView.findViewById<TextView>(R.id.textArea)
            val imageViewArea = itemView.findViewById<ImageView>(R.id.imageArea)
            val bookmarkArea = itemView.findViewById<ImageView>(R.id.bookmarkArea)


            // 북마크 클릭했을때 색칠되게
            // key리스트들이 bookmarkIdList에 포함되어있는지
            if(bookmarkIdList.contains(key)){
                bookmarkArea.setImageResource(R.drawable.bookmark_color)
            }else{
                bookmarkArea.setImageResource(R.drawable.bookmark_white)
            }


            // ContentModel에서 받아온 하나하나의 아이템들을 가져와서 title을 넣어주겠다
            contentTitle.text = item.title

            // 이미지 불러오기
            Glide.with(context)
                .load(item.imageUrl)
                .into(imageViewArea)    // imageUrl을 imageViewArea변수에 집어넣겠다

        }
    }


}

BookmarkRVAdapter.kt

 

일단 북마크프레그먼트에다가 북마크한것을 추가해줄것이기때문에 fragment_bookmark.xml로 가서 리사이클러뷰를 추가해준다

 

그리고 BookmarkFragment로 가서 BookmarkRVAdapter를 만들고, 리사이클러뷰와 어뎁터를 연결하고 BookmarkRVAdapter에 대한 정보를 다 집어넣어준다  

package com.example.mysololife.fragments

class BookmarkFragment : Fragment() {

    private lateinit var binding : FragmentBookmarkBinding

    private val TAG = BookmarkFragment::class.java.simpleName

    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)


        // 1. 전체 카테고리에 있는 컨텐츠 데이터들을 다 가져옴
        getCategoryData()

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

        // 3. 전체 컨텐츠 중에서, 사용자가 북마크한 정보만 가져옴
        rvAdapter = BookmarkRVAdapter(requireContext(), items, itemKeyList, bookmarkIdList)

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

        rv.layoutManager = GridLayoutManager(requireContext(),2)


    }
    

      ...


}

BookmarkFragment.kt

 

 

근데 북마크탭에 내가 북마크한 컨텐츠만 들어가야되는데, 이렇게 코드를 짜주면 모든 컨텐츠들이 다 들어가는 문제가 발생한다. 영상에서 보이는 요런 문제가 발생한다...

 

 

그래서 내가 북마크한 컨텐츠만 들어가도록 코드를 조금 수정해보겠다

 

getCategoryData()함수에서 bookmarkList가 키값을 포함하고 있으면 아이템들을 넣어주도록 코드를 수정했다

package com.example.mysololife.fragments

class BookmarkFragment : Fragment() {

    private lateinit var binding : FragmentBookmarkBinding

    private val TAG = BookmarkFragment::class.java.simpleName

    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.bookmartRV
        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.storeTap.setOnClickListener {
            it.findNavController().navigate(R.id.action_bookmarkFragment_to_storeFragment)

        }

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

        }

        return binding.root
    }

    private fun getCategoryData(){

        // 전체 데이터 가져오기
        val postListener = object : ValueEventListener {
            override fun onDataChange(dataSnapshot: DataSnapshot) {

                for (dataModel in dataSnapshot.children){

                    Log.d(TAG,dataModel.toString())

                    val item = dataModel.getValue(ContentModel::class.java)

                    // 3. 전체 컨텐츠 중에서, 사용자가 북마크한 정보만 가져옴
                    // bookmarkList가 키값을 포함하고 있으면 값들을 넣어줌
                    if (bookmarkIdList.contains(dataModel.key.toString())){
                        items.add(item!!)
                        itemKeyList.add(dataModel.key.toString())
                    }

                }
                rvAdapter.notifyDataSetChanged()
            }

            override fun onCancelled(databaseError: DatabaseError) {
                // Getting Post failed, log a message
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        // 전체 데이터 받아옴
        FBRef.category1.addValueEventListener(postListener)
        FBRef.category2.addValueEventListener(postListener)
        FBRef.category3.addValueEventListener(postListener)
        FBRef.category4.addValueEventListener(postListener)
        FBRef.category5.addValueEventListener(postListener)
        FBRef.category6.addValueEventListener(postListener)
        FBRef.category7.addValueEventListener(postListener)
        FBRef.category8.addValueEventListener(postListener)

    }


    // 북마크 데이터 가져오기
    private fun getBookmarkData(){

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

                for (dataModel in dataSnapshot.children){

                    Log.e(TAG, dataModel.toString())
                    bookmarkIdList.add(dataModel.key.toString())

                }
                // 1. 전체 카테고리에 있는 컨텐츠 데이터들을 다 가져옴
                getCategoryData()

            }

            override fun onCancelled(databaseError: DatabaseError) {
                // Getting Post failed, log a message
                Log.w("ContentListActivity", "loadPost:onCancelled", databaseError.toException())
            }
        }
        // 북마크 데이터받아옴
        FBRef.bookmarkRef.child(FBAuth.getUid()).addValueEventListener(postListener)

    }

}

BookmarkFragment.kt

 

이렇게 일부 코드를 수정해주면 내가 북마크한 컨텐츠들이 잘 나오는것을 볼수있다