title: How to give business logic to the ViewModel Kotlin?
body: <p>I'm working on a training project as a student, but I can't figure out how to transfer my business logic from <code>NewItemActivity</code> to the <code>NewItemViewModel</code>. It turned out that I have all the logic for validating and creating the ItemModel inside the fragment. It's not good to do this, these are all parts of the business logic that need to be given to the viewModel. How can I transfer business logic to the ViewModel, but at the same time keep the application working correctly? Otherwise I tried and everything broke for me.</p>
  <p>NewItemActivity.kt</p>
  <pre><code>class NewItemActivity : AppCompatActivity() {
  
      private val calendar: Calendar = Calendar.getInstance()
      private val viewModel: NewItemViewModel by viewModels(factoryProducer = {
          NewItemViewModel.Factory()
      })
  
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_new_item)
  
          val saveButton = findViewById&lt;Button&gt;(R.id.saveButton)
          val editDate = findViewById&lt;EditText&gt;(R.id.editDate)
  
          val date = SimpleDateFormat(&quot;dd.MM.yyyy&quot;)
          val dateDefault = date.format(calendar.timeInMillis)
          editDate.setText(dateDefault)
  
          editDate.setOnClickListener {
              showDatePickerDialog()
          }
  
          saveButton.setOnClickListener {
              checkStateDescriptionLayout()
  
              if (checkStateTitleLayout()) return@setOnClickListener
              if (checkStateDescriptionLayout()) return@setOnClickListener
  
              val newItem = ItemModel(
                  title = editTitle.text.toString(),
                  description = editDescription.text.toString(),
                  date = Date(),
                  isFavorite = false
              )
  
              viewModel.saveNewItem(newItem)
  
              Toast.makeText(this, &quot;New item added&quot;, Toast.LENGTH_SHORT).show()
              finish()
          }
  
          textChangedListener()
      }
  
      private fun showDatePickerDialog() {
          val datePickerDialog = DatePickerDialog(
              this@NewItemActivity,
              { _, year, monthOfYear, dayOfMonth -&gt;
                  val selectedDate: String =
                      dayOfMonth.toString() + &quot;.&quot; + (monthOfYear + 1) + &quot;.&quot; + year
                  editDate?.setText(selectedDate)
              },
              calendar.get(Calendar.YEAR),
              calendar.get(Calendar.MONTH),
              calendar.get(Calendar.DAY_OF_MONTH)
          )
          datePickerDialog.datePicker.maxDate = calendar.timeInMillis
          datePickerDialog.show()
      }
  
      private fun checkStateTitleLayout(): Boolean {
          val titleLayout = findViewById&lt;TextInputLayout&gt;(R.id.editTitleLayout)
          val checkTitleLayoutState = titleLayout.editText?.text?.toString()
          val fieldIsRequired = getString(R.string.fieldIsRequired)
  
          val error: Boolean = checkTitleLayoutState!!.isEmpty()
          if (error) titleLayout.error = fieldIsRequired
  
          return error
      }
  
      private fun checkStateDescriptionLayout(): Boolean {
          val descriptionLayout = findViewById&lt;TextInputLayout&gt;(R.id.editDescriptionLayout)
          val checkDescriptionLayoutState = descriptionLayout.editText?.text?.toString()
          val fieldIsRequired = getString(R.string.fieldIsRequired)
  
          val error: Boolean = checkDescriptionLayoutState!!.isEmpty()
          if (error) descriptionLayout.error = fieldIsRequired
  
          return error
      }
  
      private fun textChangedListener() {
          val titleLayout = findViewById&lt;TextInputLayout&gt;(R.id.editTitleLayout)
          val descriptionLayout = findViewById&lt;TextInputLayout&gt;(R.id.editDescriptionLayout)
  
          titleLayout.editText?.addTextChangedListener(object : TextWatcher {
              override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
              override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
              override fun afterTextChanged(s: Editable?) {
                  titleLayout.error = null
                  titleLayout.isErrorEnabled = false
              }
          })
  
          descriptionLayout.editText?.addTextChangedListener(object : TextWatcher {
              override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
              override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
              override fun afterTextChanged(s: Editable?) {
                  descriptionLayout.error = null
                  descriptionLayout.isErrorEnabled = false
              }
          })
      }
  }
  </code></pre>
  <p>NewItemViewModel.kt</p>
  <pre><code>class NewItemViewModel(
      private val repository: MyItemsRepository
  ) : ViewModel() {
  
      fun saveNewItem(item: ItemModel) = repository.saveNewItem(item)
  
      class Factory : ViewModelProvider.Factory {
          override fun &lt;T : ViewModel?&gt; create(modelClass: Class&lt;T&gt;): T {
              return NewItemViewModel(MyItemsRepositoryImpl.getInstance()) as T
          }
      }
  }
  </code></pre>