Как мне сохранить предыдущее действие при запуске нового намерения?

#android #kotlin

#Android #котлин

Вопрос:

У меня есть два занятия. Одна из них — домашняя страница с кнопкой для добавления динамической кнопки, а вторая страница — это два текста для редактирования. Итак, вы нажимаете кнопку на главной странице и переходите на вторую страницу, где вводите два текста редактирования, и вас отправляют обратно на главную страницу, где создается динамическая кнопка, настроенная на один из редактируемых текстов. Я сделал инфлятор, который позволяет вам вернуться ко второму действию с помощью кнопки, но он запускает новое второе действие, поэтому предыдущие введенные тексты редактирования исчезли. Как мне заставить их остаться?

Главная страница:

     package com.example.quest

import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.widget.Button
import android.widget.LinearLayout
import androidx.preference.PreferenceManager
import com.google.android.material.floatingactionbutton.FloatingActionButton

class MainActivity : AppCompatActivity() {
    private val questionActivityCode = 2
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<FloatingActionButton>(R.id.btn2).setOnClickListener{
            startActivityForResult(Intent(this@MainActivity, SecondActivity::class.java), questionActivityCode)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == questionActivityCode amp;amp; resultCode == Activity.RESULT_OK) {
            createNewButtonWithText(data?.getStringExtra("test") ?: "")
        }
    }

    private fun createNewButtonWithText(text: String)
    {
        val newbutton = Button(this@MainActivity)
        val layout = findViewById<LinearLayout>(R.id.mainlayout)
        newbutton.text = text
        newbutton.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
        newbutton.width=1010
        newbutton.height=300
        newbutton.gravity = Gravity.CENTER
        newbutton.translationX= 65F
        newbutton.setTextColor(Color.parseColor("#FFFFFFFF"))
        newbutton.setBackgroundColor(Color.parseColor("#250A43"))
        layout.addView(newbutton)

        val inflator = layoutInflater
        val builder = AlertDialog.Builder(this)
        val intent = Intent(this@MainActivity, SecondActivity::class.java)

        newbutton.setOnClickListener{
            val dialogLayout = inflator.inflate(R.layout.text, null)
            with(builder) {
                setTitle(newbutton.text)
                setPositiveButton("Edit"){dialog, which ->
                    startActivity(intent)
                }
                setNegativeButton("Cancel"){dialog, which ->
                    Log.d("Main", "Negative button clicked")
                }
                setView(dialogLayout)
                show()
        }
    }
}}
 

Второе действие:

     package com.example.quest

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceManager
import com.google.android.material.floatingactionbutton.FloatingActionButton

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        val question = findViewById<EditText>(R.id.question)
        val answer = findViewById<EditText>(R.id.answer)

        findViewById<FloatingActionButton>(R.id.btn3).setOnClickListener {
            val questiontext = question.text.toString()
            val answertext = answer.text.toString()
            val sharedPre = PreferenceManager.getDefaultSharedPreferences(this@SecondActivity).edit()
            sharedPre.putString("question", questiontext)
            sharedPre.putString("answer", answertext)
            sharedPre.apply()


            val returnIntent = Intent()
            returnIntent.putExtra("test", questiontext)
            setResult(Activity.RESULT_OK, returnIntent)

            finish()
        }
    }

    }
 

Ответ №1:

Если вы посмотрите на жизненный цикл действия после создания действия и при переходе от одного действия к следующему, действие будет уничтожено и будет создано новое действие. Простым способом сохранения этих данных может быть использование общих настроек, с помощью которых вы можете сохранять данные, когда пользователь вводит их во втором действии, и перед тем, как увеличить второе действие, проверьте, не являются ли данные sharedprefs равными null, и используйте данные для обновления действия, иначе просто создайте новое действие.

Комментарии:

1. Я попробовал использовать общие настройки, но по какой-то причине это не сработало. Не могли бы вы, пожалуйста, показать мне пример кода, который мог бы работать?

Ответ №2:

Используете ли вы архитектуру MVVM? Вероятно, вам следует сохранить все свои значения в ViewModel и вызывать эти значения между действиями в ViewModel , так как View (Activity / Fragment) отвечает только за задачи, связанные с пользовательским интерфейсом.

Вот простой пример

SharedViewModel Модель общего просмотра

 class SharedViewModel : ViewModel() {

   // ViewModel that holds data-related values
   var question: String ?= null
   var answer: Stirng ?= null   

}
 

Вторая активность

 class SecondActivity : AppCompatActivity() {

  private val sharedViewModel: SharedViewModel by viewModels() <-- add your viewmodel here

    override fun onCreate(savedInstanceState: Bundle?) {
      
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        val question = findViewById<EditText>(R.id.question)
        val answer = findViewById<EditText>(R.id.answer)


        // Step 1 - Check viewmodel's value and assign it back to edittext
        if(sharedViewModel.question != null) {
            question.text = sharedViewModel.question
        } 

        if(sharedViewModel.answer != null) {
            answer.text = sharedViewModel.answer
        }

        // Step 2 - Assign your value into viewmodel
        findViewById<FloatingActionButton>(R.id.btn3).setOnClickListener {

            sharedViewModel.question = question.text.toString()
            sharedViewModel.answer = answer.text.toString()
            
            returnIntent.putExtra("test", questiontext)
            setResult(Activity.RESULT_OK, returnIntent)

            finish()
        }
    }

    }
 

Дополнительные

  1. onActivityResult скоро будет устаревшим в API 30, это лучше, что вы можете узнать ActivityResultContract
  2. Попробуйте использовать databinding , так как это помогает сократить количество шаблонов, поскольку вы используете kotlin.
  3. Постарайтесь адаптироваться к MVVM architecture нему, так как это очень поможет вам в разработке приложений для Android.

Комментарии:

1. это правильный ответ для вас? или что вам еще нужно? Пожалуйста, дайте мне несколько отзывов. Спасибо