Rxjava2 просмотр кликов в адаптере ресайклера

Я использую версию моментального снимка rxbindings, совместимую с rxjava2, и все работает отлично, но я не знаю, как обрабатывать события кликов внутри адаптера recyclerView. Я пытался использовать «rxjava 1 way», но это не сработало.

RxJava 1.0:

class RecyclerAdapter ... {
    private final PublishSubject<Int> onClickSubject = PublishSubject.create();

    Observable<Int> getItemClickSignal() {
        return onClickSubject;
    }

    @Override
    public void onBindViewHolder(EcommerceAdapter.ViewHolder holder, int position) {
        RxView.clicks(holder.itemView)
                     .map(aVoid -> position)
                     .subscribe(mOnClickSubject);
    }
}

и в деятельности:

class Activity ... {

    mAdapter.getItemClickSignal()
            .subscribe(new Subscriber<Int>() {
                @Override
                public void onCompleted() {}

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                }

                @Override
                public void onNext(int position) {
                   Log.d(TAG, position);
                }
            });
}

RxJava 2.0:

mAdapter.getItemClickSignal()
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(@NonNull Integer integer) throws Exception {
                     Log.d(TAG, position);                        
                }
            });

Тот же подход не работает с rxjava2 и не выдает никаких исключений, и я не мог понять, почему.


person mayosk    schedule 03.03.2017    source источник


Ответы (1)


Я не знаю, поняли ли вы это уже, но вы должны обрабатывать событие clicks внутри класса ViewHolder.

   class RecyclerAdapter extends RecyclerView.Adapter<ViewHolder> {

   private final PublishSubject<Int> onClickSubject = PublishSubject.create();

   Observable<Int> getItemClickSignal() {
      return onClickSubject;
   }

   public class ViewHolder extends RecyclerView.ViewHolder{
    // All your fields

     public ViewHolder(View itemView) {
         super(itemView);
           RxView.clicks(itemView)
                 .map(__ -> getAdapterPosition())
                 .subscribe(mOnClickSubject);
     }
  }

     @Override
     public void onBindViewHolder(EcommerceAdapter.ViewHolder holder, int 
       position) {

     }
   }


class Activity ... {

     mAdapter.getItemClickSignal()
        .subscribe(new Subscriber<Int>() {
            @Override
            public void onCompleted() {}

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onNext(int position) {
               Log.d(TAG, position);
            }
        });

}

Я сделал что-то подобное, и я использовал rxbinding2 с rxjava2, и это сработало отлично!

person Regulo    schedule 17.06.2017
comment
Подождите, вы переводите PublishSubject в наблюдаемый? Разве это не должно быть сделано с onClickSubject.hide() ? - person Tuby; 18.06.2017
comment
Привет, @Tuby! Ты прав! Я должен использовать onClickSubject.hide(), в противном случае я привожу PublishSubject к наблюдаемому, который уже является наблюдаемым. - person Regulo; 18.06.2017
comment
да, но это означает, что вам нужно создать внутренний класс viewholder, что является плохой идеей, потому что вы сохраняете ссылку на внешний класс - person mayosk; 26.06.2017