发布到PublishSubject
时,在我的程序中仅发布第一个发布的对象。我的程序的一些上下文:
我有SomeActivity
,还有一个RecyclerView
。在我的Recycler.ViewHolder
中,我点击了。在onclick方法中,我将一个对象发布到PublishSubject。
在SomeActivity中,我订阅了onCreate
中的PublishSubject。运行我的应用程序时,我可以看到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);
}
}
简而言之,订阅只为该活动接收/发送一次的某个“ eventype”。
有什么建议吗?
编辑:
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;
}