android数据绑定_带有数据绑定和协程的android recyclerview

android数据绑定

介绍 (Introduction)

If your app needs to display a scrolling list of elements based on large data sets (or data that frequently changes), you should use RecyclerView as described on this page.

如果您的应用需要基于大型数据集(或经常更改的数据)显示元素的滚动列表,则应按照此页面上的说明使用RecyclerView

Sometimes setting up RecyclerView can be complicated, but the arrival of databinding has made the process of setting up RecyclerView a little easier.

有时设置RecyclerView可能很复杂,但是数据绑定的到来使设置RecyclerView的过程变得容易一些。

In this tutorial, we will try to display data from an API in recyclerView using the databinding mechanism.

在本教程中,我们将尝试使用数据绑定机制在recyclerView中显示来自API的数据。

结果 (The result)

Image for post

创建要在RecyclerView中显示的实体 (Creating the entity to be displayed in the RecyclerView)

We will try to create a small class that represents the data that will be displayed in the recyclerView.

我们将尝试创建一个小的类,该类代表将在recyclerView中显示的数据。

After creating the entity, we have to create an interface that will allow us to use the API. We will use the data coming from this URL api.github.com/users. The getUserAsync method uses the keyword suspend to take care of the coroutines. To make it work, you need to have retrofit 2.6 or higher. For more info about using retrofit with the coroutine, I advise you to have a look at this article link.

创建实体后,我们必须创建一个允许我们使用API​​的接口。 我们将使用来自此URL api.github.com/users的数据。 getUserAsync方法使用关键字suspend来维护协程。 为了使其正常工作,您需要安装2.6或更高版本。 有关将协程与改型一起使用的更多信息,建议您查看此文章链接

ViewModel (The ViewModel)

For the sake of simplicity, the small application that we will develop will be able to get its information only from a single source. In our case, it will only be the API, that’s why the UserViewModel takes as a parameter and object of type UserApi.

为了简单起见,我们将开发的小型应用程序将只能从单一来源获取其信息。 在我们的例子中,仅是API,这就是为什么UserViewModelUserApi类型的参数和对象作为参数。

UserViewModel.kt
UserViewModel.kt

To get an idea of the loading status, I created a small utility class, the LoadingState class.

为了了解加载状态,我创建了一个小的实用程序类LoadingState类。

LoadingState.kt
LoadingState.kt

将ViewModel连接到活动 (Connecting the ViewModel to the activity)

Once the ViewModel is ready, we now need to link it to our activity using the instruction by viewModel<UserViewModel>() provided by koin.

一旦ViewModel准备就绪,我们现在需要使用koin提供的viewModel <UserViewModel>()的指令将其链接到我们的活动。

MainActivity.kt
MainActivity.kt

As you can see, the activity is linked to the layout using the generic method setContentView of the DataBindingUtil class which has as type parameter the ActivityMainBinding class. The reference of the current activity and the layout that will be attached to the activity, the ActivityMainBinding class is generated from the layout activity_main.xml.

如您所见,活动是使用DataBindingUtil类的通用方法setContentView链接到布局的,该方法的类型参数为ActivityMainBinding类。 当前活动和将附加到该活动的布局的引用, ActivityMainBinding类是从布局activity_main.xml生成的

The following code returns an object of type ActivityMainBinding which has a lifecyclerOwner property to which we have assigned the reference of the current activity and another viewModel property to which we have assigned the viewModel we have recently retrieved. This last property is a variable declared in the file activity_main.xml as we will see in the rest of the post.

以下代码返回一个ActivityMainBinding类型的对象,该对象具有一个lifecyclerOwner属性(已为其分配当前活动的引用)和另一个viewModel属性(已向其分配了我们最近获取的viewModel)。 最后一个属性是在文件activity_main.xml中声明的变量,我们将在本文的其余部分中看到。

For the ActivityMainBinding class to be generated, you have to activate databinding in the build.gradle file of your module.

对于要生成的ActivityMainBinding类,您必须在模块的build.gradle文件中激活数据绑定。

应用程序依赖 (Application dependencies)

If you try to compile the application at this level you will get an error because until then, you haven’t created an object of type UserApi as given as a parameter to the UserViewModel class. In other words, you have to create all the Koin modules necessary for the correct operation of the application.

如果您尝试在此级别上编译应用程序,则会收到错误消息,因为在那之前,您还没有创建UserApi类型的对象作为UserViewModel类的参数。 换句话说,您必须创建正确运行应用程序所需的所有Koin模块。

Modules.kt
Modules.kt

The previous file contains 3 modules, the first netModule, contains all the dependencies for retrofit, the second retrofitServiceModule returns an instance of type UserApi, the class we used in the UserViewModel class, and for the last module viewModelModule which returns the only viewModel of our small application.

以前的文件中包含3个模块,第一netModule,包含了改造全部依赖关系,第二retrofitServiceModule返回类型UserApi,我们在UserViewModel类中使用的类的实例,并为最后一个模块viewModelModule返回的唯一视图模型我们小应用。

If you still have some problems using Koin I advise you to take a look at an article I wrote on the subject at this link

如果您在使用Koin时仍然遇到问题,建议您在此链接中查看我针对该主题撰写的文章

小号挞的孝允容器 (Start the Koin container)

App.kt
应用程式

Once startKoin has been called, Koin will read all your modules & definitions. Koin is then ready for any get() or by inject() call to retrieve the needed instance.

一旦startKoin被调用,孝允将读取所有的模块和定义。 然后,Koin准备好进行任何get()by inject()调用来检索所需的实例。

We now need to link this class to the manifest of our application, in the application element using the android:name attribute. This way, the class App will be launched at the startup of the application.

现在,我们需要使用android:name属性在应用程序元素中将该类链接到应用程序的清单。 这样,将在应用程序启动时启动App类。

Don’t forget to allow the application to connect to the internet so that retrofit can easily retrieve data from our API.

不要忘了允许应用程序连接到互联网,以便翻新版可以轻松地从我们的API中检索数据。

At this step, you can already compile the application. If you have followed the steps until now, you will see the data coming from the API in the LogCat in Android Studio.

在这一步,您已经可以编译应用程序了。 如果您已按照步骤进行操作,则您将在Android Studio的LogCat中看到来自API的数据。

通过数据绑定将数据连接到recycleView (Connect data to recycleView via databinding)

To display the data in the RecyclerView, you must first create an XML file that will represent an element of the list. If you are careful, you will notice that the User class has only 3 properties, the id, the login and the avatar of the user. We are going to use only the login and the avatar_url.

要在RecyclerView中显示数据必须首先创建一个XML文件,该文件将代表列表的元素。 如果小心,您会注意到User类只有3个属性,即id,用户的登录名和头像。 我们将仅使用登录名和avatar_url。

Image for post

The XML code in the item_user.xml file looks like this

item_user.xml文件中的XML代码如下所示

item_user.xml
item_user.xml

If we analyze this file very well, the first thing we noticed is that the ConstraintLayout is in a layout tag, and at the beginning of the file we declared a variable of type User (the User class we had created above)

如果我们很好地分析了该文件,我们注意到的第一件事是ConstraintLayout在布局标签中,并且在文件的开头,我们声明了一个类型为User的变量(我们在上面创建的User类)

The text attribute of the TextView is initialized by the value of the login property by using a structure like “@{user.login}”. You use this notation whenever you need to retrieve the value of a variable declared in a layout.

通过使用诸如“ @ {user.login}”之类的结构,由login属性的值初始化TextView的text属性 每当需要检索布局中声明的变量的值时,都可以使用此表示法。

To have access to the layout element, you need to enable databinding in your build.gradle file.

要访问layout元素,需要在build.gradle文件中启用数据绑定。

绑定适配器 (Binding Adapter)

The image view is linked to the user’s avatar URL using the setImageUrl attribute of the namespace app, if you’ve ever had to use ImageViews before you notice that this attribute doesn’t exist for an ImageView, yes it’s true this attribute doesn’t exist as long as you add it.

使用命名空间应用程序的setImageUrl属性将图像视图链接到用户的头像URL,如果曾经不得不使用ImageViews ,则注意到该ImageView不存在此属性,是的,确实该属性不存在只要添加它就存在。

To create a new attribute to a component, in our case the ImageView, you have to create a structure like this one.

要为组件创建一个新属性,在我们的示例中为ImageView ,您必须创建一个像这样的结构。

CustomViewBinding.kt
CustomViewBinding.kt

We created an extension function of the ImageView class, which takes as parameter the URL of the image to load, then we used the annotation BindingAdapter to define the name of the attribute that will be used in the XML file.

我们创建了ImageView类的扩展函数,该函数以要加载的图像的URL为参数,然后使用注释BindingAdapter定义将在XML文件中使用的属性的名称。

We just created a new attribute for the ImageView, this means that every time we start using the setImageUrl attribute, the value of this attribute will be passed to the bindImageUrl function which will use it to load the image from the URL. In our case, we used Picasso to load the image from the URL.

我们刚刚为ImageView创建了一个新属性,这意味着,每当我们开始使用setImageUrl属性时,此属性的值将传递到bindImageUrl函数,该函数将使用该函数从URL加载图像。 在本例中,我们使用Picasso从URL加载图像。

RecyclerView绑定适配器 (RecyclerView Binding Adapter)

We will use the same principle to define an attribute that we start using to link the adapter to the recyclerView directly from the XML file.

我们将使用相同的原理来定义一个属性,我们开始使用该属性直接将适配器从XML文件链接到recyclerView。

CustomViewBinding.kt
CustomViewBinding.kt

The RecyclerView in the XML will have access to the setAdapter attribute to which will be assigned an adapter that will link to the RecyclerView.

XML中的RecyclerView将有权访问setAdapter属性,将为该适配器分配一个链接到RecyclerView的适配器

RecyclerView适配器 (RecyclerView Adapter)

In order to be able to display the data in the recyclerView, you need an adapter, in our case we used a ListAdapter.

为了能够在recyclerView中显示数据,您需要一个适配器,在本例中,我们使用了ListAdapter。

As you can see I didn’t use a classic adapter, I used the ListAdapter that came with Jetpack, but it will also work with a classic adapter,

如您所见,我没有使用经典适配器,而是使用了Jetpack随附的ListAdapter,但它也可以与经典适配器一起使用,

The UserAdapter class contains an internal class which takes a binding property of type ItemUserBinding, and which inherits from the RecylerView.ViewHolder class.

UserAdapter类包含一个内部类,该类具有ItemUserBinding类型的绑定属性,并且该类继承自RecylerView.ViewHolder类。

I think it tells you something about the ItemUserBinding class. It was generated from the layout item_user.xml. In this layout, we declared a variable of type user, that’s why in the onBindViewHolder method I can have access to the user property of the binding of our viewHolder that we initialize by the value returned by the getItem(position) method.

我认为它告诉您有关ItemUserBinding类的信息。 它是从布局item_user.xml生成的 在此布局中,我们声明了一个类型为user的变量,这就是为什么在onBindViewHolder方法中,我可以访问由getItem(position)方法返回的值初始化的viewHolder绑定的用户属性。

At the moment, we declare a variable in XML it doesn’t have a value yet, that’s why we had to initialize the user declarer property in the item_user.xml file in the onBindViewHolder method.

目前,我们用XML声明了一个尚无值的变量,这就是为什么我们必须在onBindViewHolder方法的item_user.xml文件中初始化用户声明器属性的原因。

With the ListAdapter, we retrieve the data at a given position by calling the getItem(position) method. This method returns an object of the same type as the one we used as the first type parameter of the UserAdapter class in our case it’s User. If you pay attention, you will notice the ListAdapter class has two type parameters. The first one represents the class that will be managed by the list, and the second one is the viewHolder.

使用ListAdapter,我们通过调用getItem(position)方法检索给定位置的数据。 此方法返回一个与我们在本例中用作UserAdapter类的第一个类型参数的对象相同类型的对象,即User。 如果您注意的话,您会注意到ListAdapter类有两个类型参数。 第一个表示将由列表管理的类,第二个表示viewHolder。

In the onCreateViewholder method, we can retrieve the layout attached to the ItemUserBinding class by calling its inflate method by passing an object of type LayoutInflater. This method returns an object of type ItemUserbinding we can use to create an instance of type UserViewHolder.

onCreateViewholder方法中,我们可以通过使式LayoutInflater的目的调用它的充气方法取回附连到ItemUserBinding类的布局 此方法返回ItemUserbinding类型的对象,可用于创建UserViewHolder类型的实例

将RecyclerView链接到适配器 (Linking RecyclerView to Adapter)

activity_main.xml
activity_main.xml

The layout of the activity main is simple, because it has only two elements, a ProgressBar and a RecyclerView, with two variables. The first variable has the type of adapter we recently created so UserAdapter, and the second variable has the same type as the viewModel (UserViewModel).

活动主体的布局很简单,因为它只有两个元素,一个带有两个变量的ProgressBarRecyclerView 。 第一个变量具有我们最近创建的适配器的类型,即UserAdapter ,第二个变量具有与viewModel( UserViewModel)相同的类型

The RecyclerView is linked to the adapter on the line app:setAdapter=”@{adapter}”, note that the attribute setAdapter has been created above with the annotation BindingAdapter.

RecyclerViewapp:setAdapter =” @ {adapter}”行上链接到适配器,请注意,属性setAdapter已在上面创建,带有注释BindingAdapter。

We took the same technique for the ProgressBar which will start to be displayed according to the state of data loading by the attribute app:setupVisibility=”@{viewModel.loading}” which was created by the following codes.

我们对ProgressBar采用了相同的技术,该技术将根据属性app:setupVisibility =” @ {viewModel.loading}”的数据加载状态开始显示,该属性由以下代码创建。

CustomViewBinding.kt
CustomViewBinding.kt

The object returned by the loading attribute of the viewModel is of type LoadingState, this object will be passed to the method progressVisibility which is an extension of the ProgressBar class.

viewModel的loading属性返回的对象的类型为LoadingState ,该对象将传递给progressVisibility方法,该方法是ProgressBar类的扩展。

To finish, you now have to pass the data to the layout activity_main.xml from the activity, firstly the adapter and the UserViewModel, after that we have just to observe data from ViewModel and passing it to the adapter using submitList method of the listAdapter.

为了完成此任务,您现在必须将数据从活动(首先是适配器和UserViewModel)传递到布局activity_main.xml,此后,我们只需观察来自ViewModel的数据,然后使用listAdapter的SubmitList方法将其传递到适配器。

结论 (Conclusion)

Databinding with the RecyclerView is not always easy to understand at first, feel free to leave a comment if you want some clarification about a step in the tutorial.

首先,使用RecyclerView进行数据绑定并不总是那么容易理解,如果您想对本教程中的步骤进行一些说明,请随时发表评论。

If you have any kind of feedback, feel free to connect with me on Twitter.

如果您有任何反馈意见,请随时在 Twitter上 与我联系

翻译自: https://medium.com/swlh/android-recyclerview-with-data-binding-and-coroutine-3192097a0496

android数据绑定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值