[Instagram 클론 코딩] 홈페이지 만들기 (2)

mi-fasol·2023년 1월 26일
0

Instagram

목록 보기
4/4

오늘은 전에 말했던대로 홈페이지의 RecyclerView에 대해서 작성할 예정이다.

fragment_home.xml의 뷰다.

화면의 제일 위에 앱바를 구현하고, 그 아래에 ScrollView를 사용해 RecyclerView를 넣어줬다.
ScrollView를 사용하는 이유는 당연히도 게시물들을 스크롤 하며 봐야 하기 때문이다.

fragment로 작성했기 때문에 홈 액티비티에 두어도 바텀 네비게이션은 사라지지 않는다.

그럼 우선 RecyclerView의 xml 파일을 작성해보자.

이런 화면을 만들기 위해서는

이렇게 레이아웃을 배치해주면 된다.

딱히 설명할만큼 어려운 코드가 없어서 구현할 때 가장 귀찮았던 코드 하나만 소개하겠다.

// post_item_recycler.xml
<de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/proImg"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="@android:color/transparent"
            android:src="@drawable/dog"
            app:civ_border_color="@color/profileBorder"
            app:civ_border_overlay="true"
            app:civ_border_width="2dp" />

바로 이 코드인데, 게시물을 올린 유저의 프로필 사진을 보여줄 때 원 모양으로 크롭해서 보여줘야 한다.

그래서 찾아본 결과 해당 라이브러리를 사용하면 쉽게 이미지를 원으로 크롭해서 View로 만들 수 있다고 한다.

RecyclerView를 다 작성했으면 이제 홈 프래그먼트에 넣어줘야 한다.

// fragment_home.xml
<ScrollView
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

      <androidx.recyclerview.widget.RecyclerView
           android:id="@+id/rv_profile"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
           app:layout_constraintLeft_toLeftOf="parent"
           app:layout_constraintRight_toRightOf="parent"
           app:layout_constraintTop_toTopOf="parent"
           tools:listitem="@layout/post_item_recycler" />
</ScrollView>

위의 코드는 앱 바 아래에 선언해주면 된다.
ScrollView의 너비는 화면을 꽉 채우도록 했고, 높이는 RecyclerView의 크기만큼으로 설정했다.

그럼 이제 RecyclerView를 홈 프래그먼트에 넣었으니, Adapter를 사용하여 넣어줄 차례다.

어댑터 구현하려고 구글에서 찾아보면 다 Activity를 위한 어댑터 뿐이라서 구현하는데 살짝 애먹었었다.

나는 어댑터를 아래와 같이 구현했다.

class PostAdapter(private var context: Context) :
    RecyclerView.Adapter<PostAdapter.ViewHolder>() {

    val pref = UserSharedPreferences

    val pId = arrayOf(pref.getPostUserId(context), "pwfkvs341d", "iowcjvpxe_awev")
    val cId = arrayOf("eoisjfv_qohn", "poirjbg", "24rfd_ih_.1")
    val content = arrayOf(pref.getUserPost(context), "히욱", "힝구링")
    val comment = arrayOf("오오오", "오타났어", "힝")

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if (holder.pUserId.text != pref.getUserId(context)) {
            pId[0] = pref.getUserId(context)
            content[0] = pref.getUserPost(context)
        }
        holder.postId.text = pId[position]
        holder.commentId.text = cId[position]
        holder.comment.text = comment[position]
        holder.postContent.text = content[position]
        holder.pUserId.text = pId[position]

        holder.itemView.setOnClickListener { v ->
            holder.all.setOnClickListener {
                Intent(context, CommentActivity::class.java).apply {
                }.run {
                    context.startActivity(this)
                }
            }
            holder.postId.setOnClickListener {
                Intent(context, CommentActivity::class.java).apply {
                }.run {
                    context.startActivity(this)
                }
            }
            holder.postContent.setOnClickListener {
                Intent(context, CommentActivity::class.java).apply {
                }.run {
                    context.startActivity(this)
                }
            }
            holder.commentId.setOnClickListener {
                Intent(context, CommentActivity::class.java).apply {
                }.run {
                    context.startActivity(this)
                }
            }
            holder.comment.setOnClickListener {
                Intent(context, CommentActivity::class.java).apply {
                }.run {
                    context.startActivity(this)
                }
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val binding =
            PostItemRecyclerBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return ViewHolder(binding)
    }

    inner class ViewHolder(binding: PostItemRecyclerBinding) :
        RecyclerView.ViewHolder(binding.root) {

        var postId: TextView
        var postContent: TextView
        var commentId: TextView
        var comment: TextView
        var postImage: ImageView
        var userImage: ImageView
        var pUserId: TextView
        private var postLayout: LinearLayout
        var all: LinearLayout
        var heart: TextView
        private val menu: Button

        init {
            pUserId = binding.postUserId
            postId = binding.postNickname
            postContent = binding.postContent
            commentId = binding.cNickname
            comment = binding.userComment
            postImage = binding.postImage
            userImage = binding.proImg
            postLayout = binding.postLayout
            all = binding.allLayout
            heart = binding.getHeart
            menu = binding.postMenu

            val showPopUp = PopupMenu(
                context, menu
            )

            showPopUp.menu.add(Menu.NONE, 0, 0, "게시물 삭제")


            showPopUp.setOnMenuItemClickListener { menuItem ->
                val id = menuItem.itemId
                if (id == 0) {
                    pref.removePost(context)
                    Intent(context, HomeActivity::class.java).apply {
                    }.run {
                        context.startActivity(this)
                    }
                }
                false
            }

            menu.setOnClickListener {
                showPopUp.show()
            }
        }
    }
}

대충 폼만 만드느라 닉네임과 내용은 모두 하드코딩이다.

보면 shared preferences를 사용해서 넣어둔 코드도 있는데, 배열에 들어가는 pref는 그냥 원하는 문자열로 대신하면 되고 아래 showPopUp에 있는 pref는 주석 처리를 하든, 삭제를 하든 원하는 처리를 하면 된다.

그리고 onBindViewHolder에 있는 if문 pref는 배열의 pref를 문자열로 대체했다면 그냥 삭제해도 된다.

어댑터 구현 코드가 살짝 긴 관계로, 이 어댑터의 내용을 하나하나 뜯어서 해석하는 것은 다음 게시물에서 다뤄보겠다.

profile
정위블

0개의 댓글