Sunday 18 August 2019

Things after Kotlin Android Extensions

Things after Kotlin Android Extensions(KTX)

I remembered in MVVM when I have to declare ViewModel, I initialize View Model like this.
private val viewModel: MainViewModel by lazy {

    ViewModelProvider(this).get(MainViewModel::class.java)
}
but now using KTX it becomes
//when you need fragment scope
private val viewModel: MainViewModel by viewModels()

//when you need activity scope
private val viewModel: MainViewModel by activityViewModels()
And when I have to declare RecyclerView View Holder, then either I use normal findByViewId() or Databinding
class RecyclerVH(private val binding: ItemXBinding) : RecyclerView.ViewHolder(binding.root) {

    fun bind(dataB: DataB) {
    
        binding.tvNote.text = dataB.note
    }
}
but after KTX View Holder become
class RecyclerVH(private val view: View) : RecyclerView.ViewHolder(view),LayoutContainer {

    override val containerView: View?
        get() = view
        
    fun bind(dataB: DataB) {
    
        tv_note.text = dataB.note
    }
}
And same activity, fragment or custom view, when you inflate then you have to initialize data binding

in Fragment
lateint var binding:MyviewFragmentBinding
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    binding=inflater.inflate(R.layout.myview_fragment, container, false))
    return binding.root!!
}

//To access view
binding.tvNote.text="Hello Binding"
in Activity
private val binding: ActivityMyviewBinding by lazy {

    DataBindingUtil.setContentView>(this, R.layout.activity_myview)
}

//To access view
binding.tvNote.text="Hello Binding"
But after KTX, Just access view id directly, more elegant code no more binding
tv_note.text="Hello DataBinding"
And for Custom View before KTX
class MyView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener {

    val binding = MyViewBinding.inflate(LayoutInflater.from(context), this, true)
    
    init{
    
      binding.tvNote.text="Hello binding"       
   }    
}
And after KTX it becomes
class MyView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener {

init{
    MyViewBinding.inflate(LayoutInflater.from(context), this, true)
    
    tv_note.text="Hello binding"       
   }    
   
}
or use LayoutContainer
class MyView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), View.OnClickListener, LayoutContainer {

  private val view = LayoutInflater.from(context).inflate(R.layout.myview, this, true)

  override val containerView: View?
    get() = view
    init{
      tv_note.text="Hello LayoutContainer"       
   }    
}
Kotlin Android extension libraries or plugin which I have used for above sample codes
//For LayoutContainer and access view id directly.
apply plugin: 'kotlin-android-extensions' //in app build.gradle
//in android{} block
androidExtensions {
    experimental = true
}
//for viewModels and activityViewModels
androidx.fragment:fragment-ktx:$version

Things after Kotlin Android Extensions

Things after Kotlin Android Extensions(KTX) I remembered in MVVM when I have to declare ViewModel, I initialize View Model like this. p...