뷰페이저2 _특별한 페이지 설정

쿵ㅇ양·2024년 1월 28일
0

Android

목록 보기
3/30

내가 만들어야 하는 화면이고,
이런 식으로 뷰페이지를 추가하도록 하는 화면이다.

우선 나는 1번 화면까지는 뷰페이저2를 RecyclerView.Adapter를 이용해 구현해 놓은 상태였고 뷰페이지를 추가하는 페이지를 추가했어야 하는 상황!!

어떻게 할지 많이 고민이 되었고 처음에는 뷰페이저를 두개 만들어서 둘을 연결해줄까 하는 생각을 가지고 두개의 뷰페이저 어댑터를 만들어 둘을 연결해주었다
하지만 1번 뷰페이저어댑터가 호출되고 1번 뷰페이저의 마지막 페이지에서 2번 뷰페이저 어댑터를 호출하게 해서 그런지 둘이 연결은 되었지만 이어지는게 매끄럽지 않았고 이전 페이지로 스와이프?도 되지 않아서 다른 방법을 찾았다..

그러다 마지막 페이지에서 항상 추가하는 페이지가 나오도록 설정을 해주면 된다고 생각해 아이템xml에 마지막 페이지 레이아웃을 넣어주고 어댑터에서 마지막장에 이 아이템xml을 바인딩해주었다.

코드

1. item_add_profile.xml 레이아웃 작성

2. VPAdapter

//RecyclerView.Adapter 이용
class MainProfileVPAdapter : ListAdapter<MultiProfileData, RecyclerView.ViewHolder>(
    MainListDiffCallback()
) {

    //상수 정의
    companion object {
    
        //아이템의 타입을 나타내는데 사용
        private const val VIEW_TYPE_ITEM = 0
        
        //마지막에 추가되는 아이템에 대한 타입을 정의하는 데 사용
        private const val VIEW_TYPE_ADD_ITEM = 1
    }

    
    // viewType에 따라 다른 뷰홀더를 생성
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        
        //viewType이 VIEW_TYPE_ITEM인 경우
        return if (viewType == VIEW_TYPE_ITEM) {
            val binding =
                ItemMultiprofileBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            MainItemViewHolder(binding)
        
        //viewType이 VIEW_TYPE_ADD_ITEM인 경우: 마지막페이지일때
        } else {
            val binding =
                ItemAddProfileBinding.inflate(LayoutInflater.from(parent.context), parent, false)

            binding.profileAddBtn.setOnClickListener {
                Toast.makeText(parent.context, "프로필 추가", Toast.LENGTH_SHORT).show()

                val intent = Intent(parent.context, MainActivity2::class.java)
                parent.context.startActivity(intent)
            }
            
            //바인딩한 아이템 추가해 뷰홀더 반환
            MainAddItemViewHolder(binding)

        }
    }

    //RecyclerView에서 각 항목을 화면에 표시할 때 호출
    //holder 매개변수는 현재 항목에 대한 ViewHolder를 나타냄
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        
        //when 표현식을 사용하여 holder의 타입을 확인
        when (holder) {
            is MainItemViewHolder -> holder.bind(getItem(position) as MultiProfileData)
            
            // 현재 항목이 추가 아이템인 경우
            is MainAddItemViewHolder -> holder.bind()
        }
    }

    override fun getItemCount(): Int {
        
        // 마지막에 추가 항목을 위한 1을 더함
        return super.getItemCount() + 1
    }

    override fun getItemViewType(position: Int): Int {
        
        // 마지막 항목인 경우 추가 항목을 위한 VIEW_TYPE_ADD_ITEM을 반환
        return if (position < super.getItemCount()) 
        VIEW_TYPE_ITEM else VIEW_TYPE_ADD_ITEM
    }

    inner class MainItemViewHolder(private val binding: ItemMultiprofileBinding) :
        RecyclerView.ViewHolder(binding.root) {
        
        //아이템에 데이터클래스에서 정의한 데이터 넣어줌
        fun bind(item: MultiProfileData) {
            binding.multiProfileCharIv.setImageResource(item.profileImageResId)
            binding.multiProfileNameTv.text = item.name
            binding.multiProfileNumberTv.text = item.phoneNumber
        }
    }

    inner class MainAddItemViewHolder(private val binding: ItemAddProfileBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bind() {
            
        }
    }

    // RecyclerView의 아이템 갱신을 위해 사용
    class MainListDiffCallback : DiffUtil.ItemCallback<MultiProfileData>() {
        override fun areItemsTheSame(
            oldItem: MultiProfileData,
            newItem: MultiProfileData
        ): Boolean {
            return oldItem == newItem
        }

        override fun areContentsTheSame(
            oldItem: MultiProfileData,
            newItem: MultiProfileData
        ): Boolean {
            return oldItem.name == newItem.name
        }
    }


}

3. MainProfileFragment

어댑터랑 뷰페이저 연결해줌

class MainProfileFragment : Fragment() {

    lateinit var binding: FragmentMainprofileBinding
    private val multiList = mutableListOf<MultiProfileData>()
    private lateinit var vpadapter : MainProfileVPAdapter

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

        binding = FragmentMainprofileBinding.inflate(inflater, container, false)

        //밑에서 작성한 뷰페이저 연결 메서드
        initViewPager()

        return binding.root
    }

    private fun initViewPager() {
        val multiList = mutableListOf<MultiProfileData>()
		
        multiList.add(MultiProfileData(R.drawable.myprofile_character, "1", "010-1234-5678"))
        multiList.add(MultiProfileData(R.drawable.myprofile_character, "2", "010-1234-5678"))
        multiList.add(MultiProfileData(R.drawable.myprofile_character, "3", "010-1234-5678"))


        vpadapter = MainProfileVPAdapter()

        //데이터 리스트 전달
        vpadapter.submitList(multiList)

        //뷰페이저랑 어댑터 연결
        binding.mainProfileVp.adapter = vpadapter

        //첫번째 페이지부터 시작, 애니메이션 사용x
        binding.mainProfileVp.setCurrentItem(0, false)


    }
}
profile
개발을 공부하고 있는 대학생

0개의 댓글

관련 채용 정보