首页 文章

具有活动和片段的ViewModel粒度

提问于
浏览
2

这个问题围绕Android应用程序的体系结构 . When using the LifeCycle component ViewModel, is it best to have one ViewModel per fragment or one ViewModel for the parent activity, to which the Fragments are subscribed to?

我似乎不清楚如何在没有某种耦合的情况下定位类似Master-Detail片段 - 活动关系的东西 . 例如,如果每个Fragment都拥有自己的ViewModel,则不清楚Activity如何在没有耦合的情况下知道如何做出反应(接口,直接函数调用) .

1 回答

  • 0

    正如我在评论中提到的那样,没有独特的方法来实现这一点,但理想情况下,非常具体地说,对于您的主/细节关注点,让我们分析默认提供的示例:

    ItemDetialActivity 处理片段创建和显示,FAB和菜单操作 . 请注意,没有任何与用户数据相关的信息,只有"system"句柄 . 例如,我试图限制活动对导航的责任,以及你真正无法避免的菜单按钮处理 . 现在, ItemListActivity 似乎违反了这个原则,因为负责显示列表(Google示例只会在这些关注点之间产生混淆-IMHO-),我会创建一个包含 RecyclerView 及其适配器的单独片段 .

    现在到了细节 . 这是一个非常高级的骨架,希望你能利用 . 检查出来,实施它,如果有任何问题,请回来:

    public interface BaseView {
         LifecycleOwner lifecycleOwner();
    
         /* perform actions that affect a basic screen status, like hide/show progress bars and errors,  
            animate views, etc. */
    }
    
    public class BaseRepo {
        // will contain LiveData instances which will postValues()
    }
    
    public class FooRepo extends BaseRepo {
        /* will contain access to database and networking functions, either by creating instance methods 
           or enforcing with an interface, it's up to you.  */
    }
    
    public class BaseModel<P extends BasePresenter> extends ViewModel {
        protected final FooRepo fooRepo; // optional, can be on concretes
    
        <T> void subscribe(LiveData<T> liveData, Observer<T> observer) {
            liveData.observe(view.lifecycleOwner(), observer);
        }
    
        <T> void unsubscribe(LiveData<T> liveData, Observer<T> observer) {
            if (liveData != null) {
                liveData.removeObserver(observer);
            }
        }
        ...
    } 
    
    public abstract class BasePresenter<M extends BaseModel, V extends BaseView> implements LifecycleObserver {
        protected V view;
        protected M model;
    
        public void setModel(M model) {
            this.model = model;
        }
    
        public final void attachView(V view, Lifecycle lifecycle) {
            this.view = view;
            lifecycle.addObserver(this);
        }
    
        public void setPresenter(P presenter) {
            this.presenter = presenter;
            this.presenter.setModel(this);
        }
        ...
    }
    
    public abstract class BaseFragment implements BaseView {
        /* generics is highly encouraged here, I've seen examples of both BasePresenter<P> 
           and BaseView<P> */
        protected P presenter; 
    
        /* You should bind layers here, or in the concrete class, 
           either with Dagger, reflection, or some other way */ 
    
        @Override
        public LifecycleOwner lifecycleOwner() {
            return this;
        }
        ...
    }
    

    现在,对于每个具体的屏幕,您应该创建一个从基础派生的演示者,模型和片段,并在那里执行细节 . 我希望它有所帮助 .

相关问题