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