我使用MVP模式创建了一个应用程序,我找到了这个教程link,并决定在我的应用程序中实现它,以便片段与他们的活动进行通信。我将Eventbus的实现移动到对应的活动演示者和片段演示者,以便仍然使用MVP模式。现在我面临一个新问题,我的一个片段需要在活动参数中更改两件事(工具栏相关和ImageView drawable)。我可以在接受函数中以某种方式区分回调吗?
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)添加另一个evenbus,但我不认为为你想要回调活动的每个事件都有单独的eventbus是合乎逻辑的。
感谢您的帮助
更新
我遇到了另一个问题(或者至少是潜在的问题)。我添加了一个SwipeRefreshLayout来包装我的内容(这是framelayout,我将拥有的每个片段都将显示在此容器中)。我这样做的主要原因是在活动和所有片段之间实现单一界面。假设您没有网络连接我会向用户显示一条消息,向下滑动以尝试刷新当前片段。到目前为止,我已经通过将SwipeRefreshLayout添加到我拥有的每个片段来完成此操作。它基本上是相同的代码,我想将所有代码合并到活动中的一个位置。我很想使用EventBus,但据我所知,我需要将所有片段订阅到“事件”onRefresh。 如何将事件发送到适当的片段?
答案 0 :(得分:0)
我使用RxBus传输全局事件。您也可以按照自己的方式使用它。
class RxBus {
private val busSubject: Subject<ActionEvent<out Any>> =
PublishSubject.create()
fun register( onNext:
Consumer<ActionEvent<out Any>>):Disposable{
return busSubject
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onNext)
}
fun post(event: ActionEvent<out Any>) {
busSubject.onNext(event)
}
}
open class ActionEvent<T>(val action: ActionEnum
, val event: T) {
}
您可以使用String代替ActionEnum,它只是一个枚举类
当你发布内容时,
getRxBus()?.post(ActionEvent(ActionEnum.CHANGE_APP_BAR_LAYOUT,collapse))
如果您想订阅,
val disposable = rxBus.subscribe(Consumer{...})
请记得将销售处置废弃。