티스토리 뷰

반응형
SMALL

 

ViewBinding을 사용하는 이유

  • 실수로 내가 사용되야 할 곳에 id를 찾아 Import 시켜줘야 하는데 잘못해서 동일한 id를 갖는 다른 xml 을 참조할 가능성 자체가 없음. null exception
  • 선언할 때 viewType 이 잘못선언할 경우 case exception 
  • 내가 사용하고자 하는 View를 직접 바인딩 하게 되기 때문에 다른 xml 을 갖고오는 실수를 할 수 없을 뿐더러 xml 을 만들면 자동으로 바인딩 클레스를 생성해준다.

 

바인딩 클래스가 자동으로 생성되는데 클래스 이름은 

activity_main.xml > ActivityMainBinding
fragment_main.xml > FragmentMainBinding
module_item.xml > ModuleItemBinding

 

 

Kotlin Synthetic 가 나왔을 때 정말 편할꺼라 생각했지만 ? 위에서 말했듯 실수로 다른 레이아웃에 Id 가 import 될 수 있으므로 Deprecated 되었다고 한다.

 

android {

// 스튜디오 버전 4.0 이상
	buildFeatures {
        viewBinding true
    }
    
    or
    
// 스튜디오 버전 4.0 이하
    viewBinding {
    	enabled true
    }
}

 

나는 아래와 같이 사용한다. 

혹시 더 좋은 방법이 있다면 댓글로 공유좀..

 

반응형

Activity class 에서 ViewBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.recyclerView.apply {
            layoutManager = LinearLayoutManager(this@MainActivity, LinearLayoutManager.VERTICAL, false)
            adapter = RecyclerListAdapter()
        }
    }
    
    inner class RecyclerListAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
            ItemViewHolder(ViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            (holder as? ItemViewHolder)?.onBind()
        }

        override fun getItemCount(): Int = 10
    }

    inner class ItemViewHolder(private val binding: ViewItemBinding): RecyclerView.ViewHolder(binding.root) {
        fun onBind() {

            val rnd = Random()
            val color: Int =
                Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))

            with(binding) {
                bg.setBackgroundColor(color)
                index.text = adapterPosition.toString()
            }
        }
    }
}

 

Fragment class 에서 ViewBinding

  • Fragment 에서 ViewBinding 을 사용할 경우 View 보다 오래 지속되는 Fragment Lifecycle로 인해 메모리 누수가 발생할 수 있다. 그래서 Fragment 의 View를 사용하지 않을 때 ( onDestoryView ) ViewBinding 또한 null 로 만들어 누수를 없애는 것이 좋다.
class FirstFragment: Fragment() {

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

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentFirstBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.recyclerView.apply {
            layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
            adapter = RecyclerListAdapter()
        }
        
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    inner class RecyclerListAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
            ItemViewHolder(ViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            (holder as? ItemViewHolder)?.onBind()
        }

        override fun getItemCount(): Int = 10
    }

    inner class ItemViewHolder(private val binding: ViewItemBinding): RecyclerView.ViewHolder(binding.root) {
        fun onBind() {

            val rnd = Random()
            val color: Int =
                Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256))

            with(binding) {
                bg.setBackgroundColor(color)
                index.text = adapterPosition.toString()
            }
        }
    }
}

 

 

 

 

반응형
LIST
댓글