You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:07:39