[TIL] 선발대 1주차 정리

[TIL] 선발대 1주차 정리

UI 만들기

1) Toolbar

  1. TabLayout

  2. ViewPager2

  3. RecyclerView

  4. FloatingActionButton

1) 패키지 정리하기

  • 하나의 메인과
  • 두개의 프래그먼트 파일을 Package로 보기 좋게 정리해주기

2) 레이아웃 만들기

  • Ex) main_activity 레이아웃 Rename하기
buildFeatures{

  viewBinding=true

}
  • 메인 액티비티 정의하기

  • 뷰바인딩 설정

class MainActivity : AppCompatActivity() {

    private val binding by lazy { MainActivityBinding.inflate(layoutInflater) }
    private val viewPagerAdapter by lazy { MainViewPagerAdapter(this@MainActivity) }

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

        initView()
    }

    private fun initView() = with(binding) {
        //view pager adapter
        binding.viewPager.adapter = viewPagerAdapter

        // TabLayout x ViewPager2
        TabLayoutMediator(tabLayout, viewPager) { tab, position ->
            tab.setText(viewPagerAdapter.getTitle(position))
        }.attach()

        //할 일 추가버튼
        binding.fabAddTodo.setOnClickListener {
            //
        }
    }
}
  • 초기화블록 선언
  • 툴바, 뷰페이저, 버튼등 미리 선언해놓기

3) 프래그먼트 생성

class BookmarkFragment : Fragment() {
    //static 함수를 사용하여 bookmark Fragment를 가져올 수 있는 instance를 만들어줌
    companion object {
        fun newInstance() = BookmarkFragment()
    }

    private var _binding: BookmarkFragmentBinding? = null
    private val binding get()=_binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //바인딩을 넣어줘야함
        _binding=BookmarkFragmentBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //recycler View에 대한 초기화를 해줘야함
    }

    //바인딩을 위해 메모리 누수를 위해 강제적으로 초기화시켜줘야함
    override fun onDestroyView() {
        _binding=null
        super.onDestroyView()
    }
}
  • 프래그먼트 상속받기
class BookmarkFragment : Fragment() {

}
  • static 함수를 사용하여 bookmark Fragment를 가져올 수 있는 instance를 만들어줌
    • newInstance를 통해 프래그먼트를 만든다라고 생각하면됨
companion object {
  fun newInstance() = BookmarkFragment()
}

  • 프래그먼트 뷰 생성

    • onCreateView

    • onViewCreated : 프래그먼트 뷰가 생성이 된후 해야할 일을만들어주는곳

  • 프래그먼트 viewbinding선언시 아래와 같이 사용
  • 프래그먼트는 메모리 누수가 있어서 강제적으로 onDestroyView일때 _binding=null을 인위적으로 넣어줘야하도록 구글에서 권장하고 있음
private var _binding: BookmarkFragmentBinding? = null
private val binding get()=_binding!!

//
override fun onDestroyView() {
        _binding=null
        super.onDestroyView()
    }
override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //바인딩을 넣어줘야함
        _binding=BookmarkFragmentBinding.inflate(layoutInflater)
        return binding.root
    }

4) 프래그먼트 레이아웃 만들기

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/bookmark_list"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  • 리사이클러뷰 넣어줌
  • layoutManager를 사용해줌

5) 메인 어댑터 만들기

class MainViewPagerAdapter(private val activity: FragmentActivity) :
    FragmentStateAdapter(activity) {
    private val fragments = ArrayList<MainTabs>()

    init {
        fragments.add(
            MainTabs(TodoListFragment.newInstance(), "Todo")
        )
        fragments.add(
            MainTabs(BookmarkListFragment.newInstance(), "BookMark")
        )
    }
    
    fun getTitle(position: Int):String{
        return fragments[position].title
    }

    //화면의 갯수
    override fun getItemCount(): Int {
        return fragments.size
    }

    //프래그먼트를 정의해 화면에 꼿아주는것
    override fun createFragment(position: Int): Fragment {
        return fragments[position].fragment
    }

}
  • FragmentStateAdapter 를 사용하여 액티비티를 넘겨줄 수 있도록 함

  • 프래그먼트를 관리하는 방법도 여러개 있지만 arrayListData 클래스를 사용함

     data class MainTabs(
         val fragment:Fragment,//fragment
         val title: Int,//탭에 대한 제목
     )
    
      private val fragments= ArrayList<MainTabs>()
    
  • init으로 페이지 생성관리

      init {
              fragments.add(
                  MainTabs(TodoListFragment.newInstance(), "Todo") //R.string.main_home
              )
              fragments.add(
                  MainTabs(BookmarkListFragment.newInstance(), "BookMark")
              )
          }
    
  • 메인 액티비티에 어댑터 연결해주기

    • 어댑터를 전역으로 선언해주면 더 편하게 사용할 수 있게됨
      private val viewPagerAdapter by lazy {
              MainViewPagerAdapter(this)
          }
    
      //view pager adapter 메인의 initview에 넣어주기
              binding.viewPager.adapter=viewPagerAdapter
    

6) 리사이클러뷰 어댑터 만들기

class BookMarkListAdapter:RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        TODO("Not yet implemented")
    }

    override fun getItemCount(): Int {
        TODO("Not yet implemented")
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        TODO("Not yet implemented")
    }
}
class BookMarkListAdapter : RecyclerView.Adapter<BookMarkListAdapter.ViewHolder>() {
    private val list = ArrayList<BookMarkModel>()

    fun addItems(items: ArrayList<BookMarkModel>) {
        list.addAll(items)
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookMarkListAdapter.ViewHolder {
        return ViewHolder(
            BookmarkItemBinding.inflate(
                LayoutInflater.from(parent.context)
            )
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item=list[position]
        holder.bind(item)
    }

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

    class ViewHolder(
        private val binding: BookmarkItemBinding
    ) : RecyclerView.ViewHolder(binding.root) {
        fun bind(item: BookMarkModel){
            binding.title.text=item.title
        }

    }
}
  • 리사이클러뷰의 arrayListData모델 을 사용함

      data class BookMarkModel(
          val title:String
      )
    
      private val list=ArrayList<BookMarkModel>()
    
  • 리스트 추가를 위한 함수 만들기

      fun addItems(items:ArrayList<BookMarkModel>){
          list.addAll(items)
          notifyDataSetChanged()
      }
    
  • View Holder 만들기

      class ViewHolder(
              private val binding: BookmarkItemBinding
          ) : RecyclerView.ViewHolder(binding.root) {
        
          }
    
    • 껍데기를 만들고 item레이아웃을 만들어준 후
  • onCreateViewHolder 수정하기

    • 뷰홀더와 연결해준후 바인딩 해주기 이 코드는 외워야함
      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
          return ViewHolder(
              BookmarkItemBinding.inflate(
                  LayoutInflater.from(parent.context)
              )
          )
      }
    
  • onBindViewHolder

    • 아이템을 넘길 수 있도록 View Holder에 아래와 같이 bind 해주기
      fun bind(item: BookMarkModel){
          binding.title.text=item.title
      }
    
      override fun onBindViewHolder(holder: ViewHolder, position: Int) {
          val item=list[position]
          holder.bind(item)
      }
    

7 리사이클러뷰에 어댑터 넣어주기

  • 프래그먼트로 이동해 by laze로 리사이클러뷰 연결해주기

      private val recyclerViewAdapter by lazy { 
          BookMarkListAdapter()
      }
    
    • 함수 초기화를 위해 initView 로 어댑터 연결
      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
        
          initView()
      }
        
      private fun initView() {
          binding.bookmarkList.adapter=recyclerViewAdapter
      }
    
    • 테스트 데이터 넣어서 실행해보기
      //test data
      val list = ArrayList<TodoModel>()
      for (i in 0..100) {
          list.add(TodoModel("todo  $i"))
      }
      recyclerViewAdapter.addItems(list)
    

© 2023. All rights reserved.

AgileCatch