rx580网络适配器下载_通过Rx和数据绑定简化RecyclerView适配器

rx580网络适配器下载

by Ahmed Rizwan

通过艾哈迈德·里兹万(Ahmed Rizwan)

通过Rx和数据绑定简化RecyclerView适配器 (Simplifying RecyclerView Adapters with Rx & Databinding)

I recently wanted to dive deeper into Rx. So I experimented with Rx and the RecyclerView Adapters, and the results were pretty interesting!

我最近想更深入地研究Rx。 所以我尝试了Rx和RecyclerView Adapters,结果非常有趣!

With Rx in mind, I set out to accomplish three things:

考虑到Rx,我着手完成三件事:

  1. Create a RecyclerView adapter which should be generic — one adapter class to rule them all!

    创建一个应该通用的RecyclerView适配器-一个适配器类来统治它们!

  2. It should return bindings in the form of Rx streams!

    它应该以Rx流的形式返回绑定

  3. There should also be an option for supporting multiple item types!

    还应该有一个支持多种项目类型的选项!

Now, you may be thinking: this isn’t really necessary. I mean why use Rx in the first place with RecyclerAdapters? And why exactly do you need bindings as Rx streams?

现在,您可能在想:这实际上不是必需的。 我的意思是为什么首先将Rx与RecyclerAdapters一起使用? 以及为什么您确实需要绑定作为Rx流?

Well that’s true. Personally, I thought it’d be a good experiment to incorporate Rx into RecyclerView Adapters, instead of using simple callbacks or delegates. So it was sort of experimental.

好吧,那是真的。 就个人而言,我认为将Rx集成到RecyclerView Adapters中而不是使用简单的回调或委托是一个很好的实验。 所以这是实验性的。

So I wrote a library called RxRecyclerAdapter to get Rx to work with the Adapters. Let’s break down how it simplifies use of the recycler adapters.

因此,我编写了一个名为RxRecyclerAdapter的库,以使Rx与适配器一起使用。 让我们分解一下它如何简化使用 回收站适配器。

RxDataSource简化了RxRecyclerAdapter的使用 (RxDataSource simplifies the use of RxRecyclerAdapter)

Let’s say you have a beautiful String array list that you want to display:

假设您有一个漂亮的String数组列表要显示:

//Dummy DataSetdataSet = new ArrayList<>();dataSet.add("this");dataSet.add("is");dataSet.add("an");dataSet.add("example");dataSet.add("of rx!");

Here’s what you would do:

这是您要执行的操作:

  1. Enable data binding by adding this into build.gradle

    通过将其添加到build.gradle来启用数据绑定
dataBinding {      enabled = true}

2. create the layout file for the item:

2.创建项目的布局文件:

&lt;?xml version="1.0" encoding="utf-8"?>&lt;layout xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:tools="http://schemas.android.com/tools">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical"        android:padding="@dimen/activity_horizontal_margin">        <;TextView android:id="@+id/textViewItem"                  android:layout_width="match_parent"                  android:layout_height="wrap_content"                  tools:text="Recycler Item"/>    </LinearLayout></layout>

3. Create an instance of RxDataSource telling it what the dataSet type is:

3.创建一个RxDataSource实例,告诉它dataSet类型是什么:

RxDataSource&lt;String> rxDataSource = new RxDataSource<>(dataSet);

4. Compose and then cast-call bindRecyclerView (passing in the RecyclerView and layout) with LayoutBinding. Because of casting, viewHolder can infer the type of binding.

4.使用LayoutBinding编写然后强制调用bindRecyclerView(传递RecyclerView和布局)。 由于强制转换,viewHolder可以推断绑定的类型。

rxDataSource  .map(String::toLowerCase)  .repeat(10)  .&lt;ItemLayoutBinding>bindRecyclerView(recyclerView,                               R.layout.item_layout)  .subscribe(viewHolder -> {         ItemLayoutBinding b = viewHolder.getViewDataBinding();         b.textViewItem.setText(viewHolder.getItem());  });

The output will be…

输出将是…

Note that calling observeOn(AndroidSchedulers.mainThread()) would be unnecessary here, as you’re already on the mainThread. And when you call it, it causes a delay of about ~20–30 milliseconds in the stream, which would lower your frame rate.

请注意,这里不需要调用observeOn(AndroidSchedulers.mainThread()),因为您已经在mainThread上了。 当您调用它时,它会在流中造成大约20-30毫秒的延迟,这会降低帧速率。

Now for a bit more practical example.

现在来看一个更实际的例子。

Let’s say you want to dynamically update the dataSet. Let’s say you want to search the dataSet and filter out the results specific results. Here’s how that would be done:

假设您要动态更新数据集。 假设您要搜索dataSet并过滤出特定于结果的结果。 这是完成的方式:

RxTextView.afterTextChangeEvents(searchEditText).subscribe(event -> {  rxDataSource.updateDataSet(dataSet)       .filter(s -> s.contains(event.view().getText()))      .updateAdapter();});

In combination with RxBindings (because RxBindings are awesome), I register for textChange events. And when the event occurs I update the DataSet with the base dataSet!

RxBindings结合使用(因为RxBindings很棒),我注册了textChange事件。 当事件发生时,我用基本dataSet更新DataSet

Now this is important because the RxDataSource changes its dataSet instance when I call methods like filter, map and so on. So filtering needs to be done on the original dataSet, not the changed one. And… bam!

现在这很重要,因为当我调用filtermap等方法时,RxDataSource会更改其dataSet实例。 因此,需要对原始dataSet而不是更改后的dataSet进行过滤。 还有……ba!

I did come across some limitations — one being that you can’t change the type of dataSet after it has been bound with the data source. So functions like map and flatmap can’t return a different type of dataSet. But I have yet to run into a situation where I needed to be able to change the dataSet at runtime.

我确实遇到了一些限制-其中之一是您无法将dataSet与数据源绑定后更改其类型 。 因此,诸如mapflatmap之类的函数无法返回不同类型的dataSet。 但是我还没有遇到需要在运行时更改dataSet的情况。

RxRecyclerAdapter简化了多种项目类型的情况 (RxRecyclerAdapter simplifies the situations where you have multiple item types)

Now let’s say you wanted multiple Item types in your RecyclerView, for example a header and an item type. Then you would:

现在,假设您想要在RecyclerView中使用多种Item类型,例如标头和Item类型。 然后,您将:

  1. Create List of ViewHolderInfo specifying all the layouts

    创建指定所有布局的ViewHolderInfo列表

List<ViewHolderInfo> vi = new ArrayList<>();vi.add(new ViewHolderInfo(R.layout.item_layout, TYPE_ITEM)); vi.add(new ViewHolderInfo(R.layout.item_header_layout, TYPE_HEADER));

2. Create instance of RxDataSource like before:

2.像以前一样创建RxDataSource实例:

RxDataSource<String> rxDataSource = new RxDataSource<>(dataSet);

3. Compose and call bindRecyclerView passing in the recyclerView, the viewHolderInfo list and implementation of getItemViewType:

3.编写并调用bindRecyclerView,传入recyclerViewviewHolderInfo列表和getItemViewType的实现:

rxDataSource.bindRecyclerView(recyclerView, viewHolderInfoList,    new OnGetItemViewType() {      @Override public int getItemViewType(int position) {        if (position % 2 == 0) {          return TYPE_HEADER; //headers are even positions        }        return TYPE_ITEM;      }    }  ).subscribe(vH -> {    //Check instance type and bind!    final ViewDataBinding b = vH.getViewDataBinding();    if (b instanceof ItemLayoutBinding) {      final ItemLayoutBinding iB = (ItemLayoutBinding) b;      iB.textViewItem.setText("ITEM: " + vH.getItem());    } else if (b instanceof ItemHeaderLayoutBinding) {      ItemHeaderLayoutBinding hB = (ItemHeaderLayoutBinding) b;      hB.textViewHeader.setText("HEADER: " + vH.getItem());    }  });
/* and like before, you can do this as well    rxDataSource.filter(s -> s.length() > 0)               .map(String::toUpperCase)              .updateAdapter();*/

Now recyclerView would look something like:

现在recyclerView看起来像:

有关实施的一些知识 (A little about the Implementation)

发布主题 (PublishSubject)

Preface → I utilized PublishSubjects for the most part, and generics to create the adapter.

前言→我大部分时候都使用PublishSubjects通用类来创建适配器。

PublishSubject is a type of observable which can be both Observable and an Observer at the same time.

PublishSubject是一种可观察的类型,可以同时是ObservableObserver

Because it is an observer, it can subscribe to one or more Observables. And because it is an Observable, it can pass through the items it observes by reemitting them, and it can also emit new items.

因为它是观察者,所以它可以订阅一个或多个Observable。 并且由于它是可观察的,因此可以通过释放观测到的项目来传递它们,并且还可以发出新的项目。

内部构造 (Internals)

Internally, there are two adapters, which you can also access directly if you want: RxAdapter and RxAdapterForTypes.

在内部,有两个适配器,您也可以根据需要直接访问它们: RxAdapterRxAdapterForTypes

For these two, I created a generic ViewHolder implementation, which binds the layout with an instance of ViewDataBinding:

对于这两个,我创建了一个通用的ViewHolder实现,该实现将布局与ViewDataBinding实例绑定在一起:

public class SimpleViewHolder<T, V extends ViewDataBinding> extends RecyclerView.ViewHolder {    private V mViewDataBinding;    public V getViewDataBinding() {        return mViewDataBinding;    }    public T getItem() {        return mItem;    }    private T mItem;    protected void setItem(final T item) {        mItem = item;    }    public SimpleViewHolder(final View itemView) {        super(itemView);        mViewDataBinding = DataBindingUtil.bind(itemView);    }}

Then I created RxAdapter — It takes two generics:

然后,我创建了RxAdapter —它需要两个泛型:

RxAdapter&lt;DataType, LayoutBinding extends ViewDataBinding>

I created a PublishSubject for my ViewHolder, and in onBindViewHolder I call onNext. The viewHolder contains the item itself:

我为ViewHolder创建了PublishSubject ,然后在onBindViewHolder中调用onNext。 viewHolder包含项目本身:

@Overridepublic void onBindViewHolder(final SimpleViewHolder<T, V> holder, final int position) {    holder.setItem(mDataSet.get(position));    mPublishSubject.onNext(holder);}

Finally, I created a method asObservable, which returns the publishSubject as an Observable so that you can subscribe to it:

最后,我创建了一个方法asObservable,该方法将publishSubject作为Observable返回,以便您可以订阅它:

public Observable<SimpleViewHolder> asObservable(){    return mPublishSubject.asObservable();}

But wait, what about the RxDataSource? Well it’s just a wrapper for Rx Observables. It’s main purpose is to provide you with an abstraction over the two adapters and Rx methods. It basically connects everything together.

但是,等等,RxDataSource呢? 嗯,这只是Rx Observables的包装。 它的主要目的是为您提供两个适配器和Rx方法的抽象。 它基本上将所有内容连接在一起。

When I say it’s a wrapper, that means that you only get methods that are relevant to a recyclerAdapter, like filter, map, take, first, repeat and so on. It doesn’t give you methods which have something to do with threading or schedulers.

当我说它是包装器时,这意味着您只能获取与recyclerAdapter相关的方法,例如filtermaptakefirstrepeat等。 它不会为您提供与线程或调度程序有关的方法。

As the class is pretty straight-forward. You can check out the code for RxDataSource here.

由于该类很简单。 您可以在此处签出RxDataSource的代码。

That’s pretty much it… I hope you found this article useful. Do give RxAdapter a try. And if you have any questions (or suggestions), fire away!

差不多了...我希望您觉得这篇文章有用。 尝试一下RxAdapter 。 如果您有任何疑问(或建议),请开除!

Happy coding!

编码愉快!

翻译自: https://www.freecodecamp.org/news/simplifying-recyclerview-adapters-with-rx-databinding-f02ebed0b386/

rx580网络适配器下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值