In previous article 0xA05 Android 10 source code analysis: The Dialog loading and drawing process and its use in Kotlin and DataBinding are analyzed. And the DataBindingDialog base library JDataBinding based on the DataBinding encapsulation. This article focuses on the Base library JDataBinding based on the DataBinding encapsulation

JDataBinding source code: https://github.com/hi-dhl/JDataBinding

JDataBinding is based on the DataBindingActivity, DataBindingFragment, DataBindingDialog, DataBindingListAdapter base library. Welcome to the start

What is DataBinding? Check out the Google website for more details

DataBinding is Google’s DataBinding support library in Jetpack that allows you to directly bind your application’s data sources in page components

Using Kotlin’s inline, Reified, DSL, and so on, in conjunction with DataBinding, you can design more concise and maintainable code

DataBindingListAdapter

DataBindingListAdapter is based on the ListAdapter package, using less code to quickly implement RecyclerView Adapter and ViewHolder

What is a ListAdapter?

ListAdapter is a new class library from Google. It can animate more RecylerView with less code than traditional Adapter, and can automatically store the previous list. ListAdapter also added DiffUtil tool class, only when the items change to refresh, not the whole list, greatly improve the performance of RecyclerView

What is DiffUtil?

DiffUtil mainly calculates whether the list is the same in the background, and then goes back to the main thread to refresh the data. Myers Diff Algorithm is mainly used, and git Diff is used in our daily use

After introducing the basic concepts, see how DataBindingListAdapter can be used. Why do I say that RecyclerView Adapter and ViewHolder can be used quickly with less code

Step1: BaseViewHolder inheritance

Create a custom ViewHolder class that inherits the DataBindingListAdapter, using a viewHolderBinding to quickly bind the DataBinding

class TestViewHolder(view: View) : BaseViewHolder<Model>(view) {

    val binding: RecycieItemTestBinding by viewHolderBinding(view)

    override fun bindData(data: Model) {
        binding.apply {
            model = data
            executePendingBindings()
        }
    }

}
Copy the code

Step2: DataBindingListAdapter inheritance

Implement the leading and trailing Adapters and create a custom Adapter that inherits from DataBindingListAdapter

class TestAdapter : DataBindingListAdapter<Model>(Model.CALLBACK) {

    override fun viewHolder(layout: Int, view: View): DataBindingViewHolder<Model> = when (layout) {
        R.layout.recycie_item_header -> HeaderViewHolder(view)
        else -> TestViewHolder(view)
    }

    override fun layout(position: Int): Int = when (position) {
        0 -> R.layout.recycie_item_header
        getItemCount() - 1 -> R.layout.recycie_item_footer
        else -> R.layout.recycie_item_test
    }

    override fun getItemCount(): Int = super.getItemCount() + 2
}
Copy the code

The constructor passes in model. CALLBACK, which implements diffUtil. ItemCallback, which computes the difference between two non-empty items of the list. I’m going to write two abstract methods areItemsTheSame and areContentsTheSame

val CALLBACK: DiffUtil.ItemCallback<Model> = object : ItemCallback<Model>() {override fun areItemsTheSame(oldItem: Model, newItem: Model): Boolean = olditem. id == newitem. id // Check whether two Objects have the same content. override fun areContentsTheSame(oldItem: Model, newItem: Model): Boolean = true }Copy the code

Step3: Bind RecyclerView and Adapter

<data>

    <variable
        name="viewModel"
        type="com.hi.dhl.jdatabinding.demo.ui.MainViewModel" />

    <variable
        name="testAdapter"
        type="com.hi.dhl.jdatabinding.demo.ui.TestAdapter" />
</data>   

<androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:adapter="@{testAdapter}"
        app:adapterList="@{viewModel.mLiveData}"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
            
Copy the code

Use the DataBinding custom DataBinding section here. For details, see the fragment_test.xml file in demo

DataBindingDialog

In Kotlin, you should avoid using the builder pattern as much as possible. Instead, use Kotlin’s named optional parameters to construct classes and implement the builder pattern for cleaner code

In the introduction of the Builder pattern in the Effective Java book, it is described this way: In essence, the Builder pattern emulates named computable parameters, just as in Ada and Python

Fortunately, Kotlin is a transformation language with named optional arguments, and DataBindingDialog implements the Dailog Builder pattern using Kotlin’s named optional argument constructor class with a secondary encapsulation in DataBinding, Combined with the DataBinding DataBinding feature, Dialog is much more compact and easy to use

Step1: DataBindingDialog inheritance

class AppDialog( context: Context, val title: String? = null, val message: String? = null, val yes: AppDialog.() -> Unit ) : DataBindingDialog(context, R.style.AppDialog) { private val mBinding: DialogAppBinding by binding(R.layout.dialog_app) init { requireNotNull(message) { "message must be not null" } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestWindowFeature(Window.FEATURE_NO_TITLE) mBinding.apply { setContentView(root)  display.text = message btnNo.setOnClickListener { dismiss() } btnYes.setOnClickListener { yes() } } } }Copy the code

Step2: Concise invocation

AppDialog(
        context = this@MainActivity,
        message = msg,
        yes = {
            // do something
        }).show()
Copy the code

DataBindingActivity

Functions and constructors in Kotlin support named optional parameters, making it more flexible to use. In DataBindingActivity, use Kotlin’s powerful inline and reified features to implement type parameters and initialize the View more succinctly

Inheritance DataBindingActivity

class MainActivity : DataBindingActivity() {
    private val mBinding: ActivityMainBinding by binding(R.layout.activity_main)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding.apply {
            dialog.setOnClickListener {
                val msg = getString(R.string.dialog_msg)
                AppDialog(
                        context = this@MainActivity,
                        message = msg,
                        yes = {
                            Toast.makeText(this@MainActivity, msg, Toast.LENGTH_SHORT).show()
                        }).show()
            }
        }
    }
}
Copy the code

DataBindingFragment

How to use Kotlin’s inline and reified View to initialize a DataBindingFragment

Inherited from DataBindingFragment

class FragmentTest : DataBindingFragment() { val testViewModel: MainViewModel by viewModel() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup? , savedInstanceState: Bundle? ) : View? { return binding<FragmentTestBinding>( inflater, R.layout.fragment_test, container ).apply { viewModel = testViewModel testAdapter = TestAdapter() lifecycleOwner = this@FragmentTest }.root } }Copy the code

DataBindingActivity, DataBindingFragment, DataBindingDialog, and DataBindingListAdapter base libraries based on DataBinding encapsulation. Click JDataBinding to check it out and welcome start

JDataBinding source code: https://github.com/hi-dhl/JDataBinding

reference

github.com/.. BaseRecyc…

conclusion

Dedicated to share a series of Android system source code, reverse analysis, algorithm, translation, Jetpack source code related articles, is trying to write a better article, if this article is helpful to you to give a star, what is not written in the article clearly, or have better advice, welcome to leave a message, welcome to learn together, Moving forward together on the technological road.

Plan to establish a most complete and latest AndroidX Jetpack related components of the actual combat project and related components of the principle of analysis article, is gradually increasing Jetpack new members, the warehouse continues to update, you can go to check: Androidx-jetpack-practice, if this warehouse is helpful to you, please give me a thumbs up and I will finish more project practices for new members of Jetpack one after another.

algorithm

Since LeetCode has a large question bank, hundreds of questions can be selected for each category. Due to the limited energy of each person, it is impossible to brush all the questions. Therefore, I sorted the questions according to the classic types and the difficulty of the questions.

  • Data structures: arrays, stacks, queues, strings, linked lists, trees…
  • Algorithms: Search algorithm, search algorithm, bit operation, sorting, mathematics,…

Each problem will be implemented in Java and Kotlin, and each problem has its own solution ideas, time complexity and space complexity. If you like algorithms and LeetCode like me, you can pay attention to my LeetCode problem solution on GitHub: Leetcode-Solutions-with-Java-And-Kotlin, come to learn together And look forward to growing with you.

Android 10 source code series

I’m writing a series of Android 10 source code analysis articles. Knowing the system source code is not only helpful in analyzing problems, but also very helpful in the interview process. If you like to study Android source code as MUCH as I do, You can follow my Android10-source-Analysis on GitHub, and all articles will be synchronized to this repository.

  • How is APK generated
  • APK installation process
  • 0xA03 Android 10 source code analysis: APK loading process of resource loading
  • Android 10 source code: APK
  • Dialog loading and drawing process and use in Kotlin, DataBinding
  • WindowManager View binding and architecture
  • 0xA07 Android 10 source code analysis: Window type and 3d view hierarchy analysis
  • More……

Tool series

  • Shortcuts to AndroidStudio that few people know
  • Shortcuts to AndroidStudio that few people know
  • All you need to know about ADB commands
  • How to get video screenshots efficiently
  • 10 minutes introduction to Shell scripting
  • How to package Kotlin + Android Databinding in your project

The reverse series

  • Dynamically debug APP based on Smali file Android Studio
  • The Android Device Monitor tool cannot be found in Android Studio 3.2