При публикации на PublishSubject
в моей программе генерируется только первый опубликованный объект.Небольшой контекст моей программы:
У меня есть SomeActivity
, с RecyclerView
.По моему Recycler.ViewHolder
у меня на клике.В методе onclick я публикую объект в PublishSubject.
В SomeActivity я подписываюсь на PublishSubject в onCreate
.Когда я запускаю свое приложение, я вижу, что только первый опубликованный объект получен в SomeActivity.PublishSubject обернут в простой пользовательский «RxBus», который я использую для обмена данными в моем приложении между различными компонентами (вместо использования интерфейсов и т. Д.).
Вот как я публикую в держателе представления:
@Override
public void onClick(View v) {
RxBus.publish(RxBus.GAME_TOUCHED, new GameEvent(data));
}
Вот как я подписываюсь в SomeActivity:
RxBus.subscribe(RxBus.GAME_TOUCHED, this, o -> {
GameEvent gameEvent = (GameEvent) o;
//Do something here...
});
Вот мой "RxBus":
public final class RxBus {
private static RxBus INSTANCE;
private static SparseArray<PublishSubject<Object>> subjectMap = new SparseArray<>();
private static Map<Object, CompositeDisposable> subscriptionsMap = new HashMap<>();
public static final int GAME_TOUCHED = 7;
@Retention(SOURCE)
@IntDef({GAME_TOUCHED})
@interface Subject {
}
private RxBus() {
}
public static synchronized RxBus get() {
if (INSTANCE == null) {
INSTANCE = new RxBus();
}
return INSTANCE;
}
@NonNull
private static PublishSubject<Object> getSubject(@Subject int subjectCode) {
PublishSubject<Object> subject = subjectMap.get(subjectCode);
if (subject == null) {
subject = PublishSubject.create();
subject.subscribeOn(AndroidSchedulers.mainThread());
subjectMap.put(subjectCode, subject);
}
return subject;
}
@NonNull
private static CompositeDisposable getCompositeDisposable(@NonNull Object object) {
CompositeDisposable compositeDisposable = subscriptionsMap.get(object);
if (compositeDisposable == null) {
compositeDisposable = new CompositeDisposable();
subscriptionsMap.put(object, compositeDisposable);
}
return compositeDisposable;
}
public static void subscribe(@Subject int subject, @NonNull Object lifecycle, @NonNull Consumer<Object> action) {
Disposable disposable = getSubject(subject).subscribe(action);
getCompositeDisposable(lifecycle).add(disposable);
}
public static void unregister(@NonNull Object lifecycle) {
CompositeDisposable compositeDisposable = subscriptionsMap.remove(lifecycle);
if (compositeDisposable != null) {
compositeDisposable.dispose();
}
}
public static void publish(@Subject int subject, @NonNull Object message) {
getSubject(subject).onNext(message);
}
}
Короче говоря, подпишитесь на определенный "тип события", полученный только один раз для действия.
Есть предложения?
РЕДАКТИРОВАТЬ:
public class QuestionAdapter extends RecyclerView.Adapter<QuestionHolder> {
private final List<Game> games = new ArrayList<>();
private final Context context;
public QuestionAdapter(Context context) {
this.context = context;
}
@NonNull
@Override
public QuestionHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
QuestionHolder questionHolder = new QuestionHolder(R.layout.layout_item_question, parent);
return questionHolder;
}
@Override
public void onBindViewHolder(@NonNull QuestionHolder holder, int position) {
holder.bind(games.get(position));
}
@Override
public int getItemCount() {
return games.size();
}
public void setData(List<Game> newGames){
games.clear();
games.addAll(newGames);
notifyDataSetChanged();
}
public void deleteItem(int position) {
RxBus.publish(RxBus.DELETE_GAME, new GameEvent(games.get(position)));
notifyDataSetChanged(); //restore view if not/after deleted
}
public Context getContext(){
return context;
}
}
РЕДАКТИРОВАТЬ 2:
RxBus.subscribe(RxBus.DELETE_GAME, this, o -> {
GameEvent gameEvent = (GameEvent) o;
Game game = gameEvent.getGame();
MaterialDialog.Builder builder = CustomMaterialDialog.areYouSure("Delete game?", this)
.onNegative((dialog, which) -> dialog.dismiss())
.onPositive((dialog, which) -> {
dialog.dismiss();
viewModel.deleteGame(game);
});
showCustomDialog(builder);
});
РЕДАКТИРОВАТЬ 3:
Изменения в адаптере:
@Override
public void onBindViewHolder(@NonNull QuestionHolder holder, int position) {
holder.bind(games.get(position));
holder.getItemView().setOnClickListener(v -> {
Game game = holder.getData();
RxBus.publish(RxBus.GAME_TOUCHED, new GameEvent(game));
});
}
И добавил это в видоискатель:
public View getItemView(){
return itemView;
}