Внедрите ViewModelProvider.Factory в другую активность с помощью кинжала - PullRequest
0 голосов
/ 01 февраля 2020

У меня есть следующее действие, когда пользователь входит в систему. Когда запрос успешен и API возвращает допустимое значение LoggedInUser Я хотел бы перейти к другому действию и все еще иметь доступ к этому LoggedInUser.

Следующее - моя loginActivity:

class LoginActivity : AppCompatActivity() {

    val vmFactory = MainViewModelFactory()
    lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        val button: Button = findViewById(R.id.button)
        button.setOnClickListener { onButtonClick() }
        val label: TextView = findViewById(R.id.counter)


        viewModel =  ViewModelProvider(this, vmFactory).get(MainViewModel::class.java)
        println("stack: ${viewModel.hashCode()}")

        viewModel.userLogin.observe(this, Observer{ user ->
            print("Debug: ${user}")
            if(user != null){
                label.text = user.user.name
                redirectToNextActivity()

            }

        })

    }


    fun onButtonClick(){
        var username: EditText = findViewById(R.id.username)
        var password: EditText = findViewById(R.id.password)
        println(username.text.toString())
        println(password.text.toString())
        viewModel.setUser(username.text.toString(), password.text.toString())
    }

    fun redirectToNextActivity(){
        println("Login done!")
        val intent = Intent(this, SampleActivity::class.java)
        startActivity(intent)
    }


}

Ниже приведены мои ViewModel и ViewModelFactory:

MainViewModel:

class MainViewModel : ViewModel(){


    var _request = MutableLiveData<LoginRequest>()

    val userLogin: LiveData<LoggedInUser> = Transformations
        .switchMap(_request){req ->
            MainRepository.authenticatePlease(req.username, req.password)
        }

    fun setUser(username: String, password: String){
        val update = LoginRequest(username, password)
        if(_request.value == update){
            return
        }
        _request.value = update
    }

}

Вот моя фабрика:

class MainViewModelFactory: ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return MainViewModel() as T
    }
}

Дело в том, что когда я пытаюсь получить фабрику в новом Деятельности, я получаю следующую ошибку:

SampleActivity has no zero argument constructor

Затем я пытался пройти в vmFactory в моем loginActivity следующим образом:

val intent = Intent(this, SampleActivity(vmFactory)::class.java)

и я все еще получаю ту же ошибку.

SampleActivity выглядит следующим образом:

class SampleActivity@Inject constructor(private val factory: ViewModelProvider.Factory) : AppCompatActivity() {

    lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sample)
        viewModel = ViewModelProvider(this, factory).get(MainViewModel::class.java)

    }
}

Любая помощь приветствуется!

1 Ответ

0 голосов
/ 01 февраля 2020
  • Не следует добавлять параметры в конструкторы Activity.

Разработчики не имеют доступа к конструкторам Android компонентов, поскольку ОС Android управляет созданием Activity, Классы BroadcastReceiver, Service, ContentProvider и Application.

Пожалуйста, проверьте дополнительную информацию: https://levelup.gitconnected.com/understanding-dependency-injection-in-android-af1bb2b7984e

  • Если вы sh в Имея доступ к LoggedInUser в Sample Activity, вы можете отправить объект в качестве дополнительного параметра в намерении

    fun redirectToNextActivity(loggedInUser: LoggedInUser) {
    println("Login done!")
    val intent = Intent(this, SampleActivity::class.java)
    intent.putExtra("extra", loggedInUser)
    startActivity(intent)
    }
    

    Или вы можете пометить класс MainViewModel как Singleton, чтобы получить один и тот же экземпляр в обеих ваших действиях

...