我如何保存在一个editText输入的值,直到应用程序完全关闭和销毁?



当我导航到菜单中的其他片段,然后返回到第一个片段时,我在一个片段中输入的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()
}
}

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

  • 创建包含8个元素的DATA类,默认为空值:

//这是对象模型

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

重要:确保你的共享视图模型创建良好

最新更新