2

I'm using rxbindings snapshot version compatible with rxjava2 and everything works perfectly, but i don't know how to handle click events inside recyclerView adapter. I tried to use "rxjava 1 way" but it doesn't work.

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);
    }
}

and in activity:

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);                        
                }
            });

The same approach doesn't work with rxjava2 neither throws any exception, and i could not figure out why.

mayosk
  • 603
  • 3
  • 14

1 Answers1

1

I don't know if you figured this out already, but you should handle clicks event inside ViewHolder class.

   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);
            }
        });

}

I did something similar and I used rxbinding2 with rxjava2 and it worked perfectly!

Regulo
  • 21
  • 2
  • Wait, are you casting PublishSubject to observable? Shouldn't that be done with `onClickSubject.hide()` ? – Tuby Jun 18 '17 at 10:20
  • 1
    Hey, @Tuby! You're right! I should be using onClickSubject.hide(), otherwise, I'm casting PublishSubject to observable, which is an observable already. – Regulo Jun 18 '17 at 11:10
  • yes but this means that you need to make viewholder inner class, which is bad idea cause you keep reference to outer class – mayosk Jun 26 '17 at 07:44