Jenya Kirmiza
Jenya Kirmiza

Reputation: 711

RX Java RecycleView

I'm not familiar with rx java. Trying to use it with recycleview. For some reason my code is not working Here is my code.

Fragment with recycle view

 public class CheeseListFragment extends Fragment {
        private final CompositeSubscription subscriptions = new CompositeSubscription();
        private  PublishSubject<String> timespanSubject;
        private final Func1<String, Observable<LiveInfo>> trendingSearch =
                new Func1<String, Observable<LiveInfo>>() {
                    @Override
                    public Observable<LiveInfo> call(String s) {
                        RadioLiveInfoObservableService radioLiveInfoObservableService=ApiProvider.getInstance().getRadioObserverInfo();
                        return radioLiveInfoObservableService.radioInfo(Type.INTERVAL)
                                .observeOn(AndroidSchedulers.mainThread())
                                .doOnError(trendingError)
                                .onErrorResumeNext(Observable.<LiveInfo>empty());
                    }
                };

        private final Action1<Throwable> trendingError = new Action1<Throwable>() {
            @Override public void call(Throwable throwable) {
                Timber.e(throwable, "Failed to get trending repositories");
            }
        };

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            timespanSubject = PublishSubject.create();
            final RecyclerView rv = (RecyclerView) inflater.inflate(
                    R.layout.fragment_cheese_list, container, false);    
            setupRecyclerView(rv);

            subscriptions.add(timespanSubject
                    .flatMap(trendingSearch)
                    .map(SearchResultToRepositoryList.instance())
                    .subscribe(adapter));
            return rv;
        }

            private SimpleStringRecyclerViewAdapter adapter;

        private void setupRecyclerView(RecyclerView recyclerView) {
            recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
             adapter=new SimpleStringRecyclerViewAdapter(getActivity(), new SimpleStringRecyclerViewAdapter.CurrentShowClickListener() {
                @Override
                public void onCurrentShowClick(Current currentShow) {
                    Intent intent = new Intent(CApplication.getAppContext(), CheeseDetailActivity.class);
                    intent.putExtra(CheeseDetailActivity.EXTRA_NAME, currentShow.getName());

                    CApplication.getAppContext().startActivity(intent);
                }
            });
            recyclerView.setAdapter(adapter);
            adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
                @Override
                public void onChanged() {
                    Toast.makeText(getActivity(),"data changed",Toast.LENGTH_SHORT).show();
                }
            });

        }

        private List<String> getRandomSublist(String[] array, int amount) {
            ArrayList<String> list = new ArrayList<>(amount);
            Random random = new Random();
            while (list.size() < amount) {
                list.add(array[random.nextInt(array.length)]);
            }
            return list;
        }

        public static class SimpleStringRecyclerViewAdapter
                extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> implements Action1<List<Current>> {
            private List<Current> currentShows = Collections.emptyList();

            public interface CurrentShowClickListener {
                void onCurrentShowClick(Current currentShow);
            }

            private final CurrentShowClickListener currentShowClickListener;

            private final TypedValue mTypedValue = new TypedValue();
            private int mBackground;

            @Override
            public void call(List<Current> currentShows) {
                this.currentShows = currentShows;
                notifyDataSetChanged();
            }

            public SimpleStringRecyclerViewAdapter(Context context,CurrentShowClickListener currentShowClickListener) {
                context.getTheme().resolveAttribute(R.attr.selectableItemBackground, mTypedValue, true);
                mBackground = mTypedValue.resourceId;
                this.currentShowClickListener = currentShowClickListener;
            }

            @Override
            public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                ListItemView view = (ListItemView)LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.list_item, parent, false);
                view.setBackgroundResource(mBackground);
                return new ViewHolder(view);
            }

            @Override public void onBindViewHolder(ViewHolder viewHolder, int i) {
                viewHolder.bindTo(currentShows.get(i));
            }

            @Override public long getItemId(int position) {
                return position;
            }

            @Override public int getItemCount() {
                return currentShows.size();
            }

            public final class ViewHolder extends RecyclerView.ViewHolder {
                public final ListItemView itemView;
                private Current currentShow;

                public ViewHolder(ListItemView itemView) {
                    super(itemView);
                    this.itemView = itemView;
                    this.itemView.setOnClickListener(new View.OnClickListener() {
                        @Override public void onClick(View v) {
                            currentShowClickListener.onCurrentShowClick(currentShow);
                        }
                    });
                }

                public void bindTo(Current currentShow) {
                    this.currentShow = currentShow;
                    itemView.bindTo(currentShow);
                }
            }
        }
    }

SearchToResultRepositoryList

public final class SearchResultToRepositoryList implements Func1<LiveInfo, List<Current>> {
  private static volatile SearchResultToRepositoryList instance;

  public static SearchResultToRepositoryList instance() {
    if (instance == null) {
      instance = new SearchResultToRepositoryList();
    }
    return instance;
  }

  @Override public List<Current> call(LiveInfo repositoriesResponse) {
    List<Current> currents=new ArrayList<>();
    currents.add(repositoriesResponse.getCurrent());
    return currents;
  }
}

REST

public interface RadioLiveInfoObservableService {

    @GET("/api/live-info/")
    Observable<LiveInfo> radioInfo(
            @Query("type") Type type);
}

It's just doing nothing. I tried to debug it trendingSearch.call is not called at all.

I can make it work only this way. But still i want to know how to it with subscription

RadioLiveInfoObservableService radioLiveInfoObservableService=ApiProvider.getInstance().getRadioObserverInfo();
radioLiveInfoObservableService.commits(Type.INTERVAL)
        .observeOn(AndroidSchedulers.mainThread())
        .doOnError(trendingError)
        .onErrorResumeNext(Observable.<LiveInfo>empty()).subscribe(new Action1<LiveInfo>() {
    @Override
    public void call(LiveInfo liveInfo) {
        List<Current> currents=new ArrayList<Current>();
        currents.add(liveInfo.getCurrent());
        adapter.currentShows=currents;
        adapter.notifyDataSetChanged();
        rv.setAdapter(adapter);
    }
});

Upvotes: 1

Views: 1772

Answers (1)

kjones
kjones

Reputation: 5823

That's a lot of code to digest looking for errors, but off the top of my head nothing will happen until timeSpanSubject.onNext() is called. I don't see this called anywhere but maybe there is some missing code you are not showing.

If there is no missing code that calls timeSpanSubject.onNext(), then you could use either a BehaviorSubject which will emit an item when first subscribed to or another Observable such as timer or interval depending on what you are trying to do. timer would subscribe to your trendingSearch Observable a single time whereas using an interval would subscribe multiple times.

Upvotes: 1

Related Questions