代码之家  ›  专栏  ›  技术社区  ›  Augusto Carmo

Android ViewModel和startActivity

  •  0
  • Augusto Carmo  · 技术社区  · 6 年前

    ViewModel LiveData 在这个过程中,一个疑问出现了。

    Activity ?

    视图模型

    ActivityAViewModel : ViewModel() {
        // ...
    
        fun openActivityB(context: Context) {
            context.startActivity(...)
        }
    
        // ...
    }
    
    ActivityA {
        // ...
    
        fun onSomethingHappened() {
            viewModel.openActivityB(this)
        }
    
        // ...
    }
    

    如果没有,在这种情况下,最正确的做法是什么?

    1 回复  |  直到 6 年前
        1
  •  4
  •   Arka Prava Basu    6 年前

    我喜欢射击项目。:天

    就像大家说的那样 ViewModel Context 或者引用包含 上下文 startActivity .

    我要做的是有一个包含事件数据的LiveData。此事件将根据您的业务逻辑从您的ViewModel中激发(可能您正在显示倒计时,并在它结束时移动到下一个活动?)。它是一个 LiveData

    你可能想看看 SingleLiveEvent

        2
  •  5
  •   Alexandr Bahach    6 年前

    您应该从activity调用startActivity,而不是viewmodel。如果您想从viewmodel打开它,您需要在viewmodel中创建带有一些导航参数的livedata,并观察活动中的livedata。

        3
  •  3
  •   no_cola    6 年前

    所以,viewmodel应该不知道视图以及它如何向用户显示信息。

    /**
     * Activity (as view) responsible only for gathering actions and intentions from user and
     * show result state.
     * View must know "What user want". View knows meaning its interface.
     * Click on button 'login' means INTENTION to login somewhere.
     * This intention pass to ViewModel to process it and wait some changing state from LiveData.
     * For example implemented as Actions.
     */
    public class LoginActivity extends AppCompatActivity {
        private LoginViewModel mLoginViewModel;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mLoginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
            mLoginViewModel.getAction().observe(this, new Observer<Action>() {
                @Override
                public void onChanged(@Nullable final Action action) {
                    if(action != null){
                        handleAction(action);
                    }
                }
            });
    
            //Emulate user intention
            mLoginViewModel.userWantToLogin("0123456789", "admin");
        }
    
        private void handleAction(@NonNull final Action action) {
            switch (action.getValue()){
                case Action.SHOW_WELCOME:
                    //show Activity. 
                    break;
                case Action.SHOW_INVALID_PASSWARD_OR_LOGIN:
                    //show Toast
                    break;
            }
        }
    }
    
        public class LoginViewModel extends ViewModel {
            //Stores actions for view.
            private MutableLiveData<Action> mAction = new MutableLiveData<>();
    
            public LiveData<Action> getAction() {
                return mAction;
            }
    
            /**
             * Takes intention to login from user and process it.
             *
             * @param password Dummy password.
             * @param login Dummy login.
             */
            public void userWantToLogin(String password, String login){
                if(validateInfo(password, login)){
                    showWelcomeScreen();
                }else {
                    showPasswordOrLoginInvalid();
                }
            }
    
            /*
             * Changes LiveData. Does not act directly with view.
             * View can implement any way to show info
              * to user (show new activity, alert or toast)
             */
            private void showPasswordOrLoginInvalid() {
                mAction.setValue(new Action(Action.SHOW_INVALID_PASSWARD_OR_LOGIN));
            }
    
            /*
             * Changes LiveData. Does not act directly with view.
             * View can implement any way to show info
             * to user (show new activity, alert or toast)
             */
            private void showWelcomeScreen() {
                mAction.setValue(new Action(Action.SHOW_WELCOME));
            }
    
            //As example of some logic.
            private boolean validateInfo(String password, String login) {
                return password.equals("0123456789") && login.equals("admin");
            }
        }
    
    public class Action {
        public static final int SHOW_WELCOME = 0;
        public static final int SHOW_INVALID_PASSWARD_OR_LOGIN = 1;
        private final int mAction;
    
        public Action(int action) {
            mAction = action;
        }
    
        public int getValue() {
            return mAction;
        }
    }
    
        4
  •  1
  •   Farruh Habibullaev    6 年前

    如果viewmodel对活动一无所知,这将是一个不错的设计选择。基本上,viewmodel和activity扮演可观察和观察的角色。ViewModel作为存储库、业务模型或编排层的包装器,提供了反应式的数据流,并起到了显著的作用。这意味着,作为观察者,多个活动或片段可以监听一个视图模型。

    因此,最好保持糟糕的耦合,不要把一个特定的活动紧绑在一个视图模型上,但是移动开发人员之间的一个普遍惯例是,他们更喜欢为一个活动/片段创建一个视图模型。

    如果您有需要上下文的refinition或okhttp或其他库,请通过dagger2或Koin DI库传递上下文。这将是一个干净的建筑。

        5
  •  0
  •   Mohammed Mahmoud    6 年前

    Application AndroidViewModel ,您应该扩展 AndroidViewModel公司 这只是一个 ViewModel 应用 参考。

        6
  •  0
  •   Zain    6 年前

    ViewModels 设计用于保存和管理 单曲 Activity

    不应将应用程序上下文、活动或视图对象保存到 ViewModel ;因为 视图模型 设计用于保存与这些内容(上下文、视图…)相关的数据,以便在配置更改(如屏幕旋转)时保存这些数据(因此 视图模型 不是为了保存数据本身(上下文、活动或视图),而是为了保存与它们相关的数据。

    视图模型 视图模型 父活动的。

    ;父活动将相应停止,因此 视图模型

    请检查一下 this 讨论了解更多信息