[TIL] 230825 회고

서정한·2023년 8월 25일
0

내일배움캠프 7기

목록 보기
41/66

Intro

  • 오늘은 당근마켓의 클론(가칭 사과마켓)을 주 작업으로 진행하였다. 작업하면서 가장 고민했던부분은 Interface의 사용이었다.

Interface?

  • interface는(현재까지 내가 정리하고 아는 범위에서) 간단하게 규약이라고 한다. Actvitiy끼리 서로 통신할때, 어떻게 할지를 미리 정해놓고 정해진대로 주고받는것이다. 마치 당근마켓같다..!
  • 개념정의는 이해가되었다. 그렇다면 이것을 어떻게 정의하여 사용할것인가?

실례(RecyclerviewAdapter의 item 클릭처리)

  • 제목의 부분을 구현하는데 많은 고민이 되었다. 개념은 알겠는데 이걸 실제로 구현해서 사용하려고하니까 너무 막막했다. 그래서 블로그들을 찾아보고 나름 개발순서를 정리해보려고한다.

    1. interface정의

        interface onRecyclerViewItemClickListener {
            fun onItemClick(view: View, position: Int)
        }
      
        interface onRecyclerViewItemLongClickListener {
            fun onItemLongClick(view: View, position: Int)
        }
    2. 실제 OnClick 구현(Adapter)
      - 나는 이부분에서 가장 막막했다. 내가 하고싶은일은 item을 클릭했을때 해당 item의 값을 다른 Activity로 넘겨주고싶은데.. 이부분을 메인에서와 Adapter 두부분에 구현해주는게 막막했다. 일단은 Adapter에 View.OnClickListener를 상속받아주고 그 다음 내가 클릭한 itemView에 onClickLstener를 달아준다. 내가 클릭하는 item은 결국 ViewHolder에서 구현해주기때문에 ViewHolder에 View.OnClickListener를 상속해주었다.

      class Holder(private val binding: MainItemRecyclerviewBinding, private val onItemClick: onRecyclerViewItemClickListener? = null) : RecyclerView.ViewHolder(binding.root), View.OnClickListener {
            private lateinit var image: ImageView
            private lateinit var title: TextView
            private lateinit var location: TextView
            private lateinit var price: TextView
            private lateinit var chat: Button
            private lateinit var like: Button
      
            private lateinit var mOnItemClick : onRecyclerViewItemClickListener
      
            init {
                initView()
            }
      
            private fun initView() {
                image = binding.itemMainImage
                image.clipToOutline = true
                title = binding.itemMainTitle
                location = binding.itemMainLocation
                price = binding.itemMainPrice
                chat = binding.itemMainIconChat
                like = binding.itemMainIconLike
            }
      
            fun bind(data: Product) {
                image.setImageResource(data.image)
                title.text = data.title
                location.text = data.location
                price.text = setComma(data.price) + "원"
                chat.text = data.chat
                like.text = data.like.toString()
                
                // itemView는 item 한개를 뜻함.
                // 생성할때 각 item에 onClickListener를 달아줌
                itemView.setOnClickListener(this)
            }
            
            // 실제 onClick시 동작처리하는부분
            // 우리는 Adapter를 생성할때 Main에서 받아온 interface를 넣어주었다.
            // 이렇게되면 Main에서 OnClick시 할 일이 지정된 로직이 넘어와서 클릭시 실행되는것이다.
            override fun onClick(p0: View?) {
                onItemClick?.let{
                    mOnItemClick = onItemClick
                    // layoutPosition을 가져와 넘겨줌
                    onItemClick.onItemClick(p0!!, layoutPosition)
                }
            }
        }
    3. 실제 구현(Main)

      class MainPageActivity : BasePageActivity() {
       private lateinit var binding: MainPageActivityBinding
       private lateinit var spinner: Spinner
       private lateinit var notificationButton: ImageButton
       private lateinit var recyclerview: RecyclerView
       private val spinnerItemList: MutableList<String> = mutableListOf()
       private val recyclerviewItemList : MutableList<Product> = mutableListOf()
      
       companion object {
           fun newIntent(context: Context): Intent = Intent(context, MainPageActivity::class.java)
       }
      
       override fun onCreate(savedInstanceState: Bundle?) {
           super.onCreate(savedInstanceState)
           binding = MainPageActivityBinding.inflate(layoutInflater)
           setContentView(binding.root)
      
           initView()
           initSpinner()
           initRecyclerView()
           initNotification()
       }
      
       // Main화면에서 Back Button 클릭시 처리
       override fun onBackPressed() {
           val positive = object : dialogButtonClicked {
               override fun onPositiveButtonClick() {
                   finish()
               }
           }
      
           exitDialog(positive)
       }
      
       override fun initView() {
           spinner = binding.mainSpinner
           notificationButton = binding.mainNotification
           recyclerview = binding.mainRecyclerview
       }
      
       private fun initSpinner() {
           // spinner 더미데이터 추가
           spinnerItemList.addAll(resources.getStringArray(R.array.dummy_spinner_items))
      
           val adapter = ArrayAdapter<String>(
               this,
               R.layout.spinner_item,
               spinnerItemList
           )
           adapter.setDropDownViewResource(androidx.appcompat.R.layout.support_simple_spinner_dropdown_item)
           spinner.adapter = adapter
       }
       
       private fun initRecyclerView() {
           // 더미데이터 List주입
           recyclerviewItemList.addAll(getDummyData())
           // Adapter에 구현한 interface 로직을 여기에서 구현해준다.
           val itemClickEvent = recyclerViewItemClickListener()
           val adapter = MainPageRecyclerViewAdapter(recyclerviewItemList, itemClickEvent)
           val divider = DividerItemDecoration(this, VERTICAL)
           recyclerview.addItemDecoration(divider)
      
           recyclerview.adapter = adapter
       }
      
       private fun initNotification() {
           notificationButton.setOnClickListener {
               notification(getString(R.string.notification_title), getString(R.string.notification_content))
           }
       }
       
      // 위에 설명했던 실제 구현부분.
      // Adapter에서 받은 position을 가져와 실제 Data를 접근한 후
      // Parcelable Type으로 DetailPageActivity에 넘겨준다.
       private fun recyclerViewItemClickListener() : onRecyclerViewItemClickListener{
           return object : onRecyclerViewItemClickListener {
               override fun onItemClick(view: View, position: Int) {
                   val item = recyclerviewItemList[position]
                   val intent = DetailPageActivity.newIntnet(this@MainPageActivity)
                   intent.putExtra(getString(R.string.intent_key_product), item)
                   startActivity(intent)
               }
           }
       }
    4. 결과

      • 아직 개발중이라 문장에 들어간 쓰레기값들은 다듬어줘야한다..!

Outro

  • interface를 잘 활용한다면 협업하는 상황에서 내가만든 코드를 내가 의도한대로 사용하도록 할 수 있겠다는 생각이들었다.
  • 그럼에도 interface로 추상화하는작업은 넘나 어렵다..ㅠ 끗!
profile
잘부탁드립니다!

0개의 댓글