Я создал приложение, используя шаблон MVP, я нашел этот учебник ссылка и решил внедрить ее в свое приложение, чтобы фрагменты общались своими действиями. Я переместил реализацию Eventbus в соответствующий презентатор действий и презентатор фрагментов, чтобы по-прежнему использовать шаблон MVP. Теперь я столкнулся с новой проблемой: одному из моих фрагментов нужно изменить две вещи в параметрах активности (связанные с панелью инструментов и доступные для рисования ImageView). Могу ли я как-то различить, какой обратный вызов в функции принятия?
Класс RxBus
public final class RxBus {
private static SparseArray<PublishSubject<Object>> sSubjectMap = new SparseArray<>();
private static Map<Object, CompositeDisposable> sSubscriptionsMap = new HashMap<>();
public static final int CHANGE_APP_BAR_LAYOUT = 0;
public static final int CHANGE_POSTER_IMAGE = 1;
@IntDef({CHANGE_APP_BAR_LAYOUT, CHANGE_POSTER_IMAGE})
@interface Subject {
}
private RxBus() {
// hidden constructor
}
/**
* Get the subject or create it if it's not already in memory.
*/
@NonNull
private static PublishSubject<Object> getSubject(@Subject int subjectCode) {
PublishSubject<Object> subject = sSubjectMap.get(subjectCode);
if (subject == null) {
subject = PublishSubject.create();
subject.subscribeOn(AndroidSchedulers.mainThread());
sSubjectMap.put(subjectCode, subject);
}
return subject;
}
/**
* Get the CompositeDisposable or create it if it's not already in memory.
*/
@NonNull
private static CompositeDisposable getCompositeDisposable(@NonNull Object object) {
CompositeDisposable compositeDisposable = sSubscriptionsMap.get(object);
if (compositeDisposable == null) {
compositeDisposable = new CompositeDisposable();
sSubscriptionsMap.put(object, compositeDisposable);
}
return compositeDisposable;
}
/**
* Subscribe to the specified subject and listen for updates on that subject. Pass in an object to associate
* your registration with, so that you can unsubscribe later.
* <br/><br/>
* <b>Note:</b> Make sure to call {@link RxBus#unregister(Object)} to avoid memory leaks.
*/
public static void subscribe(@Subject int subject, @NonNull Object lifecycle, @NonNull Consumer<Object> action) {
Disposable disposable = getSubject(subject).subscribe(action);
getCompositeDisposable(lifecycle).add(disposable);
}
/**
* Unregisters this object from the bus, removing all subscriptions.
* This should be called when the object is going to go out of memory.
*/
public static void unSubscribe(@NonNull Object lifecycle) {
//We have to remove the composition from the map, because once you dispose it can't be used anymore
CompositeDisposable compositeDisposable = sSubscriptionsMap.remove(lifecycle);
if (compositeDisposable != null) {
compositeDisposable.dispose();
}
}
/**
* Publish an object to the specified subject for all subscribers of that subject.
*/
public static void publish(@Subject int subject, @NonNull Object message) {
getSubject(subject).onNext(message);
}
}
Класс MainPresenter
public class MainPresenter extends BasePresenter<MainView> implements Observer<ConfigurationResponse>,Consumer<Object>
{
...
@Override
public void accept(Object o) throws Exception {
//here is the problem how can I know if I should call to changeAppBar or change Image url?
}
Класс ClientPresenter
public class ClientPresenter extends BasePresenter<SeriesSpecsView>
{
...
//I'm calling to those function withing the fragment when the user click on the ui
public void setPosterUrl(String posterUrl)
{
RxBus.publish(RxBus.CHANGE_POSTER_IMAGE,posterUrl);
}
public void setAppBarLayoutParams(boolean collapse)
{
RxBus.publish(RxBus.CHANGE_APP_BAR_LAYOUT,collapse);
}
}
Я нашел два решения этой проблемы:
1) проверять объект, вызывая функцию instanceof, не очень эффективно, и нужно ли мне будет отправлять информацию одного и того же типа между двумя событиями?
2) Добавьте еще одну шину событий, но я не думаю, что логично иметь отдельную шину событий для каждого события, для которого вы хотите иметь обратный вызов для своей деятельности.
Спасибо за вашу помощь
ОБНОВЛЕНИЕ
Я столкнулся с другой проблемой (или, по крайней мере, потенциальной проблемой). Я добавил SwipeRefreshLayout, чтобы обернуть мой контент (который является макетом кадра, каждый фрагмент, который у меня будет, будет отображаться в этом контейнере). Моя основная причина сделать это заключалась в реализации единого интерфейса между активностью и всеми фрагментами. Допустим, у вас нет сетевого подключения. Я покажу пользователю сообщение, чтобы он провел пальцем вниз, чтобы попытаться обновить текущий фрагмент. До сих пор я делал это, добавляя SwipeRefreshLayout к каждому из имеющихся у меня фрагментов. По сути, это один и тот же код, и я решил объединить весь код в одном месте в действии. Я хотел бы использовать EventBus, но, насколько я понимаю, мне нужно будет подписаться на все фрагменты на «событие» onRefresh. Как я могу отправить событие в соответствующий фрагмент?