current position:Home>Android jetpack series -- 4 How to use databinding
Android jetpack series -- 4 How to use databinding
2022-01-26 23:30:14 【Jinyang】
Definition
- Data binding , Make data objects and xml Layout binding , Support for two-way binding , yes Android Team implementation MVVM An approach to architecture ;
advantage
- Save a lot of template code :findViewById,onClickListener,setText etc. ;
- send view Decoupling from logic , Don't ask MVC So chaotic , You don't have to ask MVP That defines a lot of interfaces ;
- view Two way binding with data objects , Development only needs to focus on data objects , It doesn't matter view Various operations of ;
- xml Simple logic can be completed in ( Try not to xml To implement logic );
Easy to use
- Turn on DataBinding Support , stay module Of build.gradle Add the following code and sync project;
android {
...
dataBinding {
enabled = true
}
}
Copy code
- Create a data class ArticleItem.kt
data class ArticleItem(val title:String, val author:String,val content:String,)
Copy code
- Create a Activity, And automatically generate layout , Move the cursor to the root... In the layout file View On , Press alt+enter, Select... From the pop-up menu 「Convert to data binding layout」, The code is as follows :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
// stay data The tag declares the variables to be used 、 Full path of class
<data>
<variable
name="articleInfo"
type="com.jinyang.jetpackdemo.bean.ArticleItem" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".activity.ArticleListActivity">
<TextView
android:id="@+id/tv_article_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
// adopt @{articleInfo.title} It can be for textView Introduce the corresponding variable , You can also use default Set the default value
android:text="@{articleInfo.title,default=DataBinding The use of, }"
android:textColor="#000000"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_article_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{articleInfo.author,default=JinYang}"
android:textColor="#666666"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_article_title" />
<TextView
android:id="@+id/tv_article_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="2"
android:text="@{articleInfo.content,default= That is, data binding makes data objects and xml Layout binding supports bidirectional binding Android Team implementation MVVM An approach to architecture }"
android:textColor="#333333"
android:textSize="18sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_article_author" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
// For convenience ArticleItem Reuse of , It can also be used. import Mode introduction
<data>
<import type="com.jinyang.jetpackdemo.bean.ArticleItem"/>
<variable
name="articleInfo"
type="ArticleItem" />
</data>
// To prevent repetition, you can also import Add alias
<data>
<import
alias="ArticleInfo"
type="com.jinyang.jetpackdemo.bean.ArticleItem" />
<variable
name="articleInfo"
type="ArticleInfo" />
</data>
//binding By default, the name of the class is generated after the layout file name is changed to the hump naming method, such as :ActivityArticleListBinding
// You can customize ViewDataBinding Instance name of
<data class="ArticleListBinding">
...
</data>
Copy code
- stay Activity In Chinese, it means articleInfo assignment
class ArticleListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
<!-- val binding: ArticleListBinding = -->
val binding: ActivityArticleListBinding =
DataBindingUtil.setContentView(this, R.layout.activity_article_list)
binding.articleInfo= ArticleItem("Android Jetpack series "," Jinyang ",
"Jetpack It's a suite of multiple libraries ;\n" +
" It mainly includes architecture (Architecture)、 Basics (Foundation)、 Behavior (Behavior) 、 Interface (UI) Four aspects ;")
}
}
//DataBinding Also support in Fragment and RecyclerView Use in
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, getContentViewId(), container, false);
return binding.getRoot();
}
Copy code
One way data binding
- By default , Ordinary functions and strings are unobservable , That means , When you need to use them in a data binding layout , You can only get their values when you create them , But in subsequent operations , But we can't get the corresponding data .
- Observable There are three implementations :BaseObservable、ObservableField、ObservableCollection
BaseObservable
- BaseObservable Provides notifyChange()( Refresh all value fields ) and notifyPropertyChanged()( Update only the corresponding BR, The BR By annotating @Bindable Generate ) Two methods ;
//1. Customize Observable
class ArticleItem2(var title: String, author: String, content: String) :
BaseObservable() {
@get:Bindable
var author: String = author
set(value) {
field = value
notifyPropertyChanged(BR.author)
}
@get:Bindable
var content: String = content
set(value) {
field = value
notifyChange()
}
}
2. Activity Create a click event to call ArticleItem2 Of set Method
class ArticleListActivity : AppCompatActivity() {
lateinit var articleInfo: ArticleItem2
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityArticleListBinding =
DataBindingUtil.setContentView(this, R.layout.activity_article_list)
articleInfo = ArticleItem2(
"Android Jetpack series ", " Jinyang ",
"Jetpack It's a suite of multiple libraries ;"
)
// You can set the listener to observe changes in properties
articleInfo.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable, propertyId: Int) {
when {
BR.author == propertyId -> {
LjyLogUtil.d("BR.author")
}
BR.content == propertyId -> {
LjyLogUtil.d("BR.content")
}
BR._all == propertyId -> {
LjyLogUtil.d("BR._all")
}
else -> {
LjyLogUtil.d("propertyId:$propertyId")
}
}
}
})
binding.articleInfo=articleInfo
binding.onClickPresenter=OnClickPresenter()
}
inner class OnClickPresenter {
fun changeTitle() {
articleInfo.title="${articleInfo.title}1"
}
fun changeAuthor() {
articleInfo.author="${articleInfo.author}1"
}
fun changeContent() {
articleInfo.content="${articleInfo.content}1"
}
}
}
//3.xml add button And call the click event
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data >
<variable
name="articleInfo"
type="com.jinyang.jetpackdemo.bean.ArticleItem2" />
<variable
name="onClickPresenter"
type="com.jinyang.jetpackdemo.activity.ArticleListActivity.OnClickPresenter" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".activity.ArticleListActivity">
<TextView
android:id="@+id/tv_article_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{articleInfo.title,default=DataBinding The use of, }"
android:textColor="#000000"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_article_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{articleInfo.author,default=JinYang}"
android:textColor="#666666"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_article_title" />
<TextView
android:id="@+id/tv_article_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="2"
android:text="@{articleInfo.content,default= That is, data binding makes data objects and xml Layout binding supports bidirectional binding Android Team implementation MVVM An approach to architecture }"
android:textColor="#333333"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_article_author" />
<Button
android:id="@+id/btn_title"
android:layout_width="wrap_content"
android:text="title+1"
android:textAllCaps="false"
app:layout_constraintLeft_toLeftOf="parent"
android:onClick="@{()->onClickPresenter.changeTitle()}"
app:layout_constraintTop_toBottomOf="@+id/tv_article_content"
android:layout_margin="10dp"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_author"
android:layout_width="wrap_content"
android:text="author+1"
android:textAllCaps="false"
app:layout_constraintLeft_toRightOf="@id/btn_title"
android:layout_margin="10dp"
app:layout_constraintTop_toBottomOf="@+id/tv_article_content"
android:onClick="@{()->onClickPresenter.changeAuthor()}"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btn_content"
app:layout_constraintLeft_toRightOf="@id/btn_author"
android:onClick="@{()->onClickPresenter.changeContent()}"
android:layout_width="wrap_content"
android:layout_margin="10dp"
android:text="content+1"
android:textAllCaps="false"
app:layout_constraintTop_toBottomOf="@+id/tv_article_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Copy code
ObservableField
- Inherit BaseObservable Higher limit , need notify operation , For ease of use, you can use ObservableField;
- It's official BaseObservable Encapsulation of operations such as annotation and refresh of fields in ;
- The official native provides encapsulation of basic data types , for example ObservableBoolean、ObservableByte、ObservableChar、ObservableShort、ObservableInt、ObservableLong、ObservableFloat、ObservableDouble as well as ObservableParcelable ;
- Can also pass ObservableField Generic to declare other types
//1. Define data classes
class ArticleItem3(title: String, author: String, content: String) {
val title: ObservableField<String> = ObservableField<String>(title)
val author: ObservableField<String> = ObservableField<String>(author)
val content: ObservableField<String> = ObservableField<String>(content)
}
//2. modify OnClickPresenter Code
inner class OnClickPresenter {
fun changeTitle() {
articleInfo.title.set("${articleInfo.title.get()}1")
}
fun changeAuthor() {
articleInfo.author.set("${articleInfo.author.get()}1")
}
fun changeContent() {
articleInfo.content.set("${articleInfo.content.get()}1")
}
}
Copy code
ObservableCollection
- dataBinding Wrapper classes are also provided to replace native List and Map, Namely ObservableList and ObservableMap
//1. modify variable label
<data >
<variable
name="articleInfo"
type="androidx.databinding.ObservableMap<String,String>" />
<variable
name="onClickPresenter"
type="com.jinyang.jetpackdemo.activity.ArticleListActivity.OnClickPresenter" />
</data>
//2. modify Activity The code in
class ArticleListActivity : AppCompatActivity() {
lateinit var articleInfo: ObservableArrayMap<String, String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityArticleListBinding =
DataBindingUtil.setContentView(this, R.layout.activity_article_list)
articleInfo = ObservableArrayMap()
articleInfo.apply {
put("title", "Android Jetpack series ")
put("author", " Jinyang ")
put("content", "Jetpack It's a suite of multiple libraries ;")
}
binding.articleInfo = articleInfo
binding.onClickPresenter = OnClickPresenter()
}
inner class OnClickPresenter {
fun changeTitle() {
articleInfo["title"]+="1"
}
fun changeAuthor() {
articleInfo["author"]+="1"
}
fun changeContent() {
articleInfo["content"]+="1"
}
}
}
Copy code
Two way data binding
- Refresh the view when the data changes , When the view changes, the data can also be changed at the same time
- The way to bind variables is an equal sign more than one-way binding , The code is as follows :
<EditText
android:id="@+id/edit_content"
android:layout_width="match_parent"
android:text="@={articleInfo.content}"
android:layout_height="wrap_content"/>
Copy code
LiveData Replace Observable Fields
- It says Observable Fields, however google It is more recommended to use LiveData Replace Observable Field;
- Reference resources google Official article Use... In two steps LiveData Replace Observable Field
- LiveData Can sense the life cycle , This is related to Observable Fields It's not much of an advantage , because Data Binding You can check the activity of the view .
So for LiveData Come on , Its advantage is that it not only supports Transformations, And it can work with many architecture components ( Such as Room、WorkManager) Use with each other . Sum up , We recommend that you use LiveData. The method is very simple , There are only two steps .
//1. use LiveData Replace Observable Fields
class ArticleItem4(title: String, author: String, content: String) : ViewModel() {
var title: MutableLiveData<String> = MutableLiveData<String>().apply { value = title }
var author: MutableLiveData<String> = MutableLiveData<String>().apply { value = author }
var content: MutableLiveData<String> = MutableLiveData<String>().apply { value = content }
}
//2. Set up LiveData The lifecycle owner of (lifecycleOwner)
class ArticleListActivity : AppCompatActivity() {
lateinit var articleInfo: ArticleItem4
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityArticleListBinding =
DataBindingUtil.setContentView(this, R.layout.activity_article_list)
// The binding class of the view contains a setLifecycleOwner Method , Want to see from the data binding layout LiveData , This method has to be used .
binding.lifecycleOwner = this
articleInfo = ArticleItem4(
"Android Jetpack series ", " Jinyang ",
"Jetpack It's a suite of multiple libraries ;"
)
binding.articleInfo = articleInfo
binding.onClickPresenter = OnClickPresenter()
}
inner class OnClickPresenter {
fun changeTitle() {
articleInfo.title.value+="6"
}
fun changeAuthor() {
articleInfo.author.value+="6"
}
fun changeContent() {
articleInfo.content.value+="6"
}
}
}
Copy code
Event binding
- Event binding is also a variable binding , It's just that the set variable is the callback interface , And in our example above button Click events have been useful to
//1. Define the event method
inner class OnClickPresenter {
fun changeTitle(articleInfo:ArticleItem4) {
articleInfo.title.value+="6"
}
fun changeAuthor() {
articleInfo.author.value+="6"
}
}
//2. data I quote
<data >
<variable
name="articleInfo"
type="com.jinyang.jetpackdemo.bean.ArticleItem4" />
<variable
name="onClickPresenter"
type="com.jinyang.jetpackdemo.activity.ArticleListActivity.OnClickPresenter" />
</data>
//3. view In the binding
<Button
android:id="@+id/btn_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="title+1"
android:onClick="@{()->onClickPresenter.changeTitle(articleInfo)}"
/>
<Button
android:id="@+id/btn_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="author+1"
android:onClick="@{()->onClickPresenter.changeAuthor()}"
/>
Copy code
BindingAdapter and BindingConversion
BindingAdapter
- dataBinding Provides BindingAdapter This annotation is used to support custom attributes , Or modify the original properties ;
- Annotation values can be existing xml attribute , for example android:src、android:text etc. , You can also customize the properties and then xml Use in ;
- example 1: For each Button All text should be suffixed :“-Button”
//1. Define a method , Similar to extension function
class ArticleListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityArticleListBinding =
DataBindingUtil.setContentView(this, R.layout.activity_article_list)
binding.lifecycleOwner = this
var articleInfo: ArticleItem4 = ArticleItem4(
"Android Jetpack series ", " Jinyang ",
"Jetpack It's a suite of multiple libraries ;"
)
binding.articleInfo = articleInfo
}
}
@BindingAdapter("android:text")
fun setText(view: Button, text: String) {
view.text = "$text-Button"
}
//2. xml Set in android:text='@{"title+1"}'
<Button
android:id="@+id/btn_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{"title+1"}'
android:onClick="@{()->onClickPresenter.changeTitle(articleInfo)}"
/>
Copy code
- example 2: Custom properties
- Here with the help of a Google Official photo gallery Coil, This library is completely used Kotlin Written , And used a lot of Kotlin Characteristics of , Especially the synergetic process ;
- Coil to ImageView Added a lot of extension functions , So we can load pictures in one line of code ;
- For detailed use, please refer to : It's still in use Glide? have a look Google Official photo gallery Coil What's the difference? !
//1. add to coil rely on
implementation("io.coil-kt:coil:1.1.1")
//2. Create auxiliary data classes
class ImageBean(url: String) {
var url: MutableLiveData<String> = MutableLiveData<String>().apply { value = url }
}
//3. Define methods and add annotations
@BindingAdapter("url")
fun loadImage(view: ImageView, url: String) {
view.load(url)
LjyLogUtil.d("url:${url}")
}
//4. xml I quote
<variable
name="image"
type="com.jinyang.jetpackdemo.bean.ImageBean" />
//5. ImageView Use in
<ImageView
app:layout_constraintTop_toBottomOf="@+id/edit_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:src="@mipmap/ic_launcher"
android:layout_width="wrap_content"
app:url="@{image.url}"
android:layout_height="wrap_content"/>
//6. activity Code
lass ArticleListActivity : AppCompatActivity() {
lateinit var articleInfo: ArticleItem4
lateinit var image: ImageBean
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityArticleListBinding =
DataBindingUtil.setContentView(this, R.layout.activity_article_list)
binding.lifecycleOwner = this
articleInfo = ArticleItem4(
"Android Jetpack series ", " Jinyang ",
"Jetpack It's a suite of multiple libraries ;"
)
binding.articleInfo = articleInfo
image = ImageBean("https://pic1.zhimg.com/v2-dc32dcddfd7e78e56cc4b6f689a24979_is.jpg")
binding.image=image
binding.onClickPresenter = OnClickPresenter()
}
inner class OnClickPresenter {
fun changeTitle(articleInfo: ArticleItem4) {
articleInfo.title.value += "6"
image.url.value="https://pic3.zhimg.com/v2-e5656460688d19f7358ab3a6055fe34a_720w.jpg?source=95cc6b4a"
}
fun changeAuthor() {
articleInfo.author.value += "6"
image.url.value="https://pic2.zhimg.com/v2-f6981776beae87401991b426fbe34fdd_720w.jpg?source=95cc6b4a"
}
fun changeContent() {
articleInfo.content.value += "6"
image.url.value="https://pic2.zhimg.com/v2-f2eddc2fe0e509de5bbeeb351ddc2c61_1440w.jpg?source=172ae18b"
}
}
}
Copy code
BindingConversion
- dataBinding It also supports data conversion , Or type conversion
@BindingConversion
fun convertStringToDrawable(str: String): Drawable {
return when (str) {
" Red " -> {
ColorDrawable(Color.parseColor("#FF4081"))
}
" Blue " -> {
ColorDrawable(Color.parseColor("#3F51B5"))
}
else -> {
ColorDrawable(Color.parseColor("#344567"))
}
}
}
@BindingConversion
fun convertStringToColor(str: String): Int {
return when (str) {
" Red " -> {
Color.parseColor("#FF4081")
}
" Blue " -> {
Color.parseColor("#3F51B5")
}
else -> {
Color.parseColor("#344567")
}
}
}
<Button
android:id="@+id/btn_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background='@{" Blue "}'
android:textColor='@{" Red ",[email protected]/colorAccent}'
android:text="title+1"
android:onClick="@{()->onClickPresenter.changeTitle(articleInfo)}"
/>
<Button
android:id="@+id/btn_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background='@{" Blue "}'
android:textColor='@{" Red "}'
android:text="author+1"
android:onClick="@{()->onClickPresenter.changeAuthor()}"
/>
Copy code
Bind list data
- RecyclerView Use BaseRecyclerViewAdapterHelper+DataBinding
- Customize Adapter:
class ArticleAdapter(data: MutableList<ArticleItem4>?) :
BaseQuickAdapter<ArticleItem4, ArticleItemViewHolder>(R.layout.layout_item_article, data) {
override fun convert(holder: ArticleItemViewHolder, item: ArticleItem4) {
holder.binding?.articleInfo = item
holder.binding?.executePendingBindings()
}
class ArticleItemViewHolder(view: View) : BaseViewHolder(view) {
val binding: LayoutItemArticleBinding? = DataBindingUtil.bind(view)
}
}
// Abreast of the times BaseQuickAdapter The above customization is provided ViewHolder The implementation of the ,BaseDataBindingHolder, It can be used as follows :
class ArticleAdapter(data: MutableList<ArticleItem4>?) :
BaseQuickAdapter<ArticleItem4, BaseDataBindingHolder<LayoutItemArticleBinding> >(R.layout.layout_item_article, data) {
override fun convert(holder: BaseDataBindingHolder<LayoutItemArticleBinding>, item: ArticleItem4) {
holder.dataBinding?.articleInfo = item
holder.dataBinding?.executePendingBindings()
}
}
Copy code
- layout_item_article.xml Layout
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="articleInfo"
type="com.jinyang.jetpackdemo.bean.ArticleItem4" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_article_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{articleInfo.title,default=titleText}"
android:textColor="#000000"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_article_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{articleInfo.author,default=authorText}"
android:textColor="#666666"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_article_title" />
<TextView
android:id="@+id/tv_article_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="2"
android:text="@{articleInfo.content,default=contentText}"
android:textColor="#333333"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_article_author" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Copy code
- Activity The code is as follows
class ArticleList2Activity : AppCompatActivity() {
lateinit var mAdapter:ArticleAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
LjyLogUtil.d("onCreate")
val binding: ActivityArticleList2Binding =
DataBindingUtil.setContentView(this, R.layout.activity_article_list2)
binding.lifecycleOwner = this
binding.rvArticleList.layoutManager = LinearLayoutManager(this)
val articleList:MutableList<ArticleItem4> = ArrayList()
articleList.add(ArticleItem4("title1","jinYang","content111"))
articleList.add(ArticleItem4("title2","jinYang","content222"))
articleList.add(ArticleItem4("title3","jinYang","content333"))
mAdapter= ArticleAdapter(articleList)
binding.rvArticleList.adapter=mAdapter
binding.onClickPresenter2 = OnClickPresenter2()
}
inner class OnClickPresenter2 {
fun addArticle() {
mAdapter.addData(ArticleItem4("title${mAdapter.data.size}","jinYang","content${mAdapter.data.size}"))
LjyLogUtil.d("addArticle")
}
fun removeArticle() {
mAdapter.removeAt(0)
LjyLogUtil.d("removeArticle")
}
}
}
Copy code
- activity_article_list2.xml The layout is as follows
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="onClickPresenter2"
type="com.jinyang.jetpackdemo.activity.ArticleList2Activity.OnClickPresenter2" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activity.ArticleList2Activity">
<Button
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->onClickPresenter2.addArticle()}"
android:text="addArticle" />
<Button
android:id="@+id/btn_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{()->onClickPresenter2.removeArticle()}"
android:text="removeArticle" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_article_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</layout>
Copy code
I'm Jinyang , If you want to upgrade and learn more about dry goods , Welcome to WeChat official account. “ Jinyang said ” Receive my latest articles
copyright notice
author[Jinyang],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/01/202201262330129900.html
The sidebar is recommended
- Spring IOC container loading process
- [thinking] the difference between singleton mode and static method - object-oriented programming
- Hadoop environment setup (MySQL environment configuration)
- 10 minutes, using node JS creates a real-time early warning system for bad weather!
- Git tool
- Force deduction algorithm - 92 Reverse linked list II
- What is the sub problem of dynamic programming?
- C / C + +: static keyword summary
- Idea does not have the artifacts option when configuring Tomcat
- Anaconda can't open it
guess what you like
-
I don't know how to start this
-
Matlab simulation of transportation optimization algorithm based on PSO
-
MySQL slow log optimization
-
[Vue] as the window is stretched (larger, smaller, wider and higher), the text will not be displayed
-
Popular Linux distributions for embedded computing
-
Suzhou computer research
-
After installing SSL Certificate in Windows + tomcat, the domain name request is not successful. Please answer!!
-
Implementation time output and greetings of jQuery instance
-
The 72 year old uncle became popular. Wu Jing and Guo fan made his story into a film, which made countless dreamers blush
-
How to save computer research
Random recommended
- Springboot implements excel import and export, which is easy to use, and poi can be thrown away
- The final examination subjects of a class are mathematical programming, and the scores are sorted and output from high to low
- Two pronged approach, Tsinghua Professor Pro code JDK and hotspot source code notes, one-time learning to understand
- C + + recursive knapsack problem
- The use of GIT and GitHub and the latest git tutorial are easy to understand -- Video notes of crazy God speaking
- PostgreSQL statement query
- Ignition database test
- Context didn't understand why he got a high salary?, Nginxfair principle
- Bootstrap switch switch control user's guide, springcloud actual combat video
- A list that contains only strings. What other search methods can be used except sequential search
- [matlab path planning] multi ant colony algorithm grid map path planning [including GUI source code 650]
- [matlab path planning] improved genetic algorithm grid map path planning [including source code phase 525]
- Iinternet network path management system
- Appium settings app is not running after 5000ms
- Reactnative foundation - 07 (background image, status bar, statusbar)
- Reactnative foundation - 04 (custom rpx)
- If you want an embedded database (H2, hsql or Derby), please put it on the classpath
- When using stm32g070 Hal library, if you want to write to flash, you must perform an erase. If you don't let it, you can't write continuously.
- Linux checks where the software is installed and what files are installed
- SQL statement fuzzy query and time interval filtering
- 69. Sqrt (x) (c + + problem solving version with vs runnable source program)
- Fresh students are about to graduate. Do you choose Java development or big data?
- Java project: OA management system (java + SSM + bootstrap + MySQL + JSP)
- Titanic passenger survival prediction
- Vectorization of deep learning formula
- Configuration and use of private image warehouse of microservice architect docker
- Relearn JavaScript events
- For someone, delete return 1 and return 0
- How does Java dynamically obtain what type of data is passed? It is used to judge whether the data is the same, dynamic data type
- How does the database cow optimize SQL?
- [data structure] chain structure of binary tree (pre order traversal) (middle order traversal) (post order traversal) (sequence traversal)
- Webpack packaging optimization solution
- 5. Operation element
- Detailed explanation of red and black trees
- redhat7. 9 install database 19C
- Blue Bridge Cup notes: (the given elements are not repeated) complete arrangement (arrangement cannot be repeated, arrangement can be repeated)
- Detailed explanation of springboot default package scanning mechanism and @ componentscan specified scanning path
- How to solve the run-time exception of test times
- Detailed explanation of k8s management tool kubectl
- Android system view memory command