Android Fragments 在应用程序完全关闭并销毁之前,如何将输入的值保存在editText中?

rqmkfv5c  于 2023-01-05  发布在  Android
关注(0)|答案(1)|浏览(149)

当我导航到菜单中的其他片段,然后返回到第一个片段时,我在一个片段中输入的editText的值消失了。请详细说明如何用Kotlin代码来避免这种情况。
这是我的Kotlin密码的片段。

class EstimatorFragment : Fragment(){

    lateinit var etPerson:EditText
    lateinit var etPetrol:EditText
    lateinit var etElectricity:EditText
    lateinit var etWater:EditText
    lateinit var etLpg:EditText
    lateinit var etHouseTravel:EditText
    lateinit var etSchool:EditText
    lateinit var etVacation:EditText
    lateinit var btnGetResults:Button

     override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
     ): View? {

         val view = inflater.inflate(R.layout.fragment_estimator, container, false)

         etPerson = view.findViewById(R.id.etPerson)
         etPetrol = view.findViewById(R.id.etPetrol)
         etElectricity = view.findViewById(R.id.etElectricity)
         etWater = view.findViewById(R.id.etWater)
         etLpg = view.findViewById(R.id.etLpg)
         etHouseTravel = view.findViewById(R.id.etHouseTravel)
         etSchool = view.findViewById(R.id.etSchool)
         etVacation = view.findViewById(R.id.etVacation)
         btnGetResults = view.findViewById(R.id.btnGetResults)

         btnGetResults.setOnClickListener {

            val registerUser = JSONObject()
            registerUser.put("name", etPerson.text)

            try {

                var person = etPerson.text.toString().toDouble()
                val mul1 = (person * 364).toFloat()
                val a = mul1.toString()

                var petrol = etPetrol.text.toString().toDouble()
                val mul2 = (petrol * (0.022772278*12)).toFloat()
                val b = mul2.toString()

                var electricity = etElectricity.text.toString().toDouble()
                val mul3 = (electricity * 12*(0.92/7)).toFloat()
                val c = mul3.toString()

                var water = etWater.text.toString().toDouble()
                val mul4 = (water * 179.4/325).toFloat()
                val d = mul4.toString()

                var lpg = etLpg.text.toString().toDouble()
                val mul5 = (lpg * 280.705152/0.6).toFloat()
                val e = mul5.toString()

                var travel = etHouseTravel.text.toString().toDouble()
                val mul6 = (travel * 83.72/1.5).toFloat()
                val f = mul6.toString()

                var school = etSchool.text.toString().toDouble()
                val mul7 = (school * 502.32/9).toFloat()
                val g = mul7.toString()

                var vacation = etVacation.text.toString().toDouble()
                val mul8 = (vacation * 383.333333/2000).toFloat()
                val h = mul8.toString()

                val fin = mul1 + mul2 + mul3 + mul4 + mul5 + mul6 + mul7 + mul8
                val final = fin.toString()

                val intent = Intent(activity, Results::class.java)
                intent.putExtra("A", a)
                intent.putExtra("B", b)
                intent.putExtra("C", c)
                intent.putExtra("D", d)
                intent.putExtra("E", e)
                intent.putExtra("F", f)
                intent.putExtra("G", g)
                intent.putExtra("H", h)
                intent.putExtra("FIN", final)

                startActivity(intent)

            } catch(e:NumberFormatException ) {
                val alterDialog = AlertDialog.Builder(activity as Context)
                alterDialog.setTitle("Enter All The Values!")
                alterDialog.setMessage("Enter 0 if any block is blank!")
                alterDialog.setPositiveButton("Ok") { _, _ ->
                }

                alterDialog.create()
                alterDialog.show()
            }
        }

         return view
    }

这是连接菜单项、导航等的主活动类代码

class MainActivity : AppCompatActivity() {

    lateinit var drawerLayout: DrawerLayout
    lateinit var coordinatorLayout: CoordinatorLayout
    lateinit var toolbar: Toolbar
    lateinit var frameLayout: FrameLayout
    lateinit var navigationView: NavigationView

    var previousMenuItem: MenuItem? = null

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

        drawerLayout = findViewById(R.id.drawerLayout)
        coordinatorLayout = findViewById(R.id.coordinatorLayout)
        toolbar = findViewById(R.id.toolbar)
        frameLayout = findViewById(R.id.frame)
        navigationView = findViewById(R.id.navigationView)

        setUpToolbar()
        openEstimator()

        val actionBarDrawerToggle = ActionBarDrawerToggle(
            this@MainActivity,
            drawerLayout,
            R.string.open_drawer,
            R.string.close_drawer
        )
        drawerLayout.addDrawerListener(actionBarDrawerToggle)
        actionBarDrawerToggle.syncState()

        navigationView.setNavigationItemSelectedListener {

            if (previousMenuItem != null){
                previousMenuItem?.isChecked = false
            }

            it.isCheckable = true
            it.isChecked = true
            previousMenuItem = it

            when(it.itemId){
                R.id.estimator -> {
                    openEstimator()
                    drawerLayout.closeDrawers()
                }

                R.id.aboutApp -> {
                    supportFragmentManager.beginTransaction()
                        .replace(
                            R.id.frame,
                            AboutAppFragment()
                        )
                        .commit()

                    supportActionBar?.title = "About App"
                    drawerLayout.closeDrawers()
                }
            }
            return@setNavigationItemSelectedListener true
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        val id = item.itemId

        if (id == android.R.id.home){
            drawerLayout.openDrawer(GravityCompat.START)
        }

        return super.onOptionsItemSelected(item)
    }

    fun openEstimator(){
        val fragment = EstimatorFragment()
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.frame, fragment)
        transaction.commit()
        supportActionBar?.title = "Estimator"
        navigationView.setCheckedItem(R.id.estimator)
    }

    fun setUpToolbar() {
        setSupportActionBar(toolbar)
        supportActionBar?.title = "Toolbar Title"
        supportActionBar?.setHomeButtonEnabled(true)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

    }

    override fun onBackPressed() {
        val frag = supportFragmentManager.findFragmentById(R.id.frame)

        when(frag){
            !is EstimatorFragment -> openEstimator()

            else -> super.onBackPressed()
        }
    }
r3i60tvu

r3i60tvu1#

首先,我推荐你使用NAVIGATION COMPONENTS,你在导航方面得到了更清晰的代码。现在,如果你想保存超过2或3个片段的这些值,我建议你创建一个SharedViewModel,在那里你可以保存数据,这样你就可以在它被示例化的所有片段中得到它。

  • 使用8个元素创建一个DATA CLASS,这些元素的默认值为空:

//这是对象模型

data class EditTextData(
   var person: String = "",
   var petrol: String = "",
 ...
)
  • 现在创建SharedViewModel并创建存储值的对象,我建议您使用Flow,但也可以使用LiveData

//值将存储在这里

private var _valuesOfEditText = EditTextData()

//调用此函数以存储值

fun saveData(data: EditTextData){
       _values = data
}

//调用此函数以获取

fun getData(): Flow<EditTextData>{
   return flow {
      emit(_value)
   }
}
  • 在EstimatorFragment中,创建一个用于将数据保存在viewModel中的函数(不能是私有的)和一个用于读取数据的函数(可以是私有的)

//你可以一直调用obtainData()函数,或者你可以通过防止它只在必要的时候被调用来改进它,我把它留给你;)

fun saveDataInViewModel(){
   sharedViewModel.saveData(
      EditTextData(
         etPerson.text.toString(),
         etPetrol.text.toString(),
         ...
        )
    )
}

private fun obtainData(){
   lifecycleScope.launch {
      sharedViewModel.getData().collectLatest{data->
         if(data.person.isNotEmpty){
            etPerson.setText(data.person)
            etPetrol.setText(data.petrol)
            ...
         }
      }
   }
}
  • 终于。

在MainActivity中调用openEstimator()时,在末尾添加以下行

fragment.saveDataInViewModel()

抱歉,如果最后一步有错误,但我不这样管理我的导航,即使如此,我相信你可以找到的方式,以防有一个错误,在后者。如果你找不到一条路,让我知道。祝你有美好的一天。
还有一件事如果你有:A-〉B-〉C-〉D(片段),并且您在A、B和D中示例化此sharedViewModel,我认为当您到达D时,数据将不再存在,因为当您在C中时,SharedViewModel将消失,所以我认为为了防止它,建议只要您想保留此数据,就没有片段可以通过它示例化此SharedViewModel

    • 重要提示:确保您的共享视图模型创建良好**

相关问题