如何使用Mosby将Presenter附加到自定义派生控件(NavigationView)?
嘿,恭喜你已经在项目里把Mosby用顺了!给自定义的NavigationView加Presenter这个需求其实挺常见的,Mosby虽然常被用来绑定Activity/Fragment,但对自定义View的支持也很到位,我给你一步步拆解怎么做:
1. 让自定义NavigationView实现Mosby的MvpView接口
首先,你的自定义NavigationView得先和Mosby的View体系挂钩。如果你的导航栏有专属的视图操作(比如显示用户信息、更新菜单角标),可以先定义一个扩展自MvpView的专属接口:
// 定义专属视图接口,包含导航栏需要的所有UI操作 public interface NavigationDrawerView extends MvpView { void showUserProfile(User userInfo); void updateMenuBadge(int unreadCount); // 其他你封装的视图操作,比如动态添加菜单项的方法 }
然后让你的自定义NavigationView实现这个接口:
public class CustomNavigationView extends NavigationView implements NavigationDrawerView { // 你已经封装好的添加菜单项、动态显示子控件等逻辑 // 实现NavigationDrawerView的方法 @Override public void showUserProfile(User userInfo) { // 这里写更新用户头像、昵称的UI逻辑 } @Override public void updateMenuBadge(int unreadCount) { // 这里写更新菜单角标的逻辑 } }
2. 编写NavigationDrawerPresenter
接下来把原来MainActivity里的Presenter逻辑迁移到新的Presenter类中,继承Mosby的MvpBasePresenter,泛型参数用我们刚才定义的NavigationDrawerView:
public class NavigationDrawerPresenter extends MvpBasePresenter<NavigationDrawerView> { // 迁移过来的业务逻辑,比如加载用户信息、获取未读通知数 public void loadUserProfile() { // 模拟从数据源获取用户信息 User currentUser = UserRepository.getCurrentUser(); // 调用View方法前一定要检查View是否还绑定着,避免空指针 if (isViewAttached()) { getView().showUserProfile(currentUser); } } public void fetchUnreadNotifications() { int unreadCount = NotificationRepository.getUnreadCount(); if (isViewAttached()) { getView().updateMenuBadge(unreadCount); } } // 其他业务方法,比如处理菜单点击的逻辑也可以放在这里 }
3. 在自定义View中绑定Presenter(核心步骤)
Mosby通过MvpDelegate来管理Presenter的生命周期(绑定、解绑、状态保存),我们需要在自定义View中初始化这个Delegate,并且在View的生命周期回调中通知它:
public class CustomNavigationView extends NavigationView implements NavigationDrawerView { private MvpDelegate<? extends MvpView> mvpDelegate; private NavigationDrawerPresenter presenter; // 构造方法 public CustomNavigationView(Context context) { super(context); initMvp(); } public CustomNavigationView(Context context, AttributeSet attrs) { super(context, attrs); initMvp(); } public CustomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initMvp(); } private void initMvp() { // 初始化Presenter presenter = new NavigationDrawerPresenter(); // 使用ViewMvpDelegateImpl,第三个参数表示是否保留Presenter实例(配置更改时不重建) mvpDelegate = new ViewMvpDelegateImpl<>(this, presenter, true); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); // 通知Delegate,View已附着到窗口,绑定Presenter mvpDelegate.onAttachedToWindow(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); // 通知Delegate,View即将脱离窗口,解绑Presenter mvpDelegate.onDetachedFromWindow(); } // 给外部提供获取Presenter的方法 public NavigationDrawerPresenter getPresenter() { return presenter; } // 实现NavigationDrawerView的方法... }
4. 在MainActivity中使用
现在你可以在MainActivity的布局里直接用CustomNavigationView,然后调用Presenter的方法触发业务逻辑:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CustomNavigationView navView = findViewById(R.id.nav_view); // 比如Activity启动时加载用户信息 navView.getPresenter().loadUserProfile(); // 或者监听菜单点击时,让Presenter处理逻辑 navView.setNavigationItemSelectedListener(item -> { navView.getPresenter().handleMenuClick(item.getItemId()); return true; }); } }
额外小提示
- 记得在Presenter的所有UI调用前都用
isViewAttached()检查,避免View被销毁后出现空指针异常。 - 如果需要处理屏幕旋转等配置更改,
ViewMvpDelegateImpl已经帮你处理了Presenter的状态保存,只要第三个参数设为true即可。
这样就能完美把原来MainActivity里的Presenter逻辑迁移到独立的NavigationDrawerPresenter中,用Mosby的规范来管理视图和Presenter的绑定啦!
内容的提问来源于stack exchange,提问作者101010
相关产品推荐
相关产品推荐

