Android ViewModel和起始性



我正在学习ViewModelLiveData,并且在此过程中引起了疑问。

如果需要启动Activity,该怎么办?

可以将上下文作为参数传递给ViewModel(上下文不会存储在ViewModel内部)?

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

如果不是,在这种情况下,最正确的事情是什么?

我喜欢射击事件。:D

每个人都说ViewModel不应包含Context或引用包含Context的类。因此,从ViewModel进行startActivity不是一个好主意。

我要做的是在事件中包含一个包含数据的Livedata。此事件将根据您的业务逻辑从您的ViewModel发射(也许您正在显示倒计时,并且在其结束时,您将转移到下一个活动?)。它是LiveData,您可以在它上观察。根据此事件的数据,您可以开始您的活动。

您可能想看看SingleliveEvent

您应该从活动而不是从ViewModel中调用起始性。如果要从ViewModel打开它,则需要使用一些导航参数创建Livedata,并在活动内部观察Livedata。

IMHO,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;
    }
}

如果viewmodel对活动一无所知,那将是一个不错的设计选择。基本上,viewmodel和活动扮演可观察的和观察者的角色。ViewModel是围绕存储库或业务模型或编排层的包装器,它提供了反应性样式数据流并扮演可观察的角色。这意味着,观察者可以听一种视图模型。

因此,最好不要将一个特定的活动拧紧到一个视图模型,但是在移动开发人员中,他们更喜欢创建一个视图模型到一个活动/fragment 。

如果您具有改造或OKHTTP或其他需要上下文的库,请通过dagger2或koin di库传递上下文。这将是一个干净的体系结构。

您可以使用AndroidViewModel提供的Application上下文,您应该扩展AndroidViewModel,这只是ViewModel,它包括Application参考。

相关内容

  • 没有找到相关文章

最新更新