我的应用程序有问题,我有一个导航栏,我可以在片段之间切换,在第一个片段中,我可以查看我在第三个片段中添加的项目。我使用 MVVM 并且一切正常我在第三个片段中添加人员,它出现在第一个片段中,这里没问题,但是当我添加一些内容然后切换片段以查看更改然后切换到再次添加内容时,我的应用程序将 EditText 字符串视为空(即使它们不在应用程序的视图中)。
我在导航之间切换的代码:
fun openFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.container, fragment)
transaction.addToBackStack(fragment.tag)
transaction.commit()
}
/**Navigation menu */
val menuNavigationClickListener =
BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_products -> {
toolbar.title = "Products"
openFragment(productsFragment)
return@OnNavigationItemSelectedListener true
}
R.id.navigation_dishes -> {
toolbar.title = "Dishes"
openFragment(dishesFragment)
return@OnNavigationItemSelectedListener true
}
R.id.navigation_add -> {
toolbar.title = "Add"
openFragment(addFragment)
return@OnNavigationItemSelectedListener true
}
}
false
}
有什么建议吗?
编辑:发布第三个片段
class Add : Fragment(), AdapterView.OnItemSelectedListener {
val NEW_SPINNER_ID = 1
val ANOTHER_SPINNER_ID = 2
var productPosition: Int? = null
var dishPosition: Int? = null
fun showToast(context: FragmentActivity? = activity, message: String, duration: Int = Toast.LENGTH_LONG) {
Toast.makeText(context, message, duration) .show()
}
/**Spinner implementation TODO */
override fun onNothingSelected(parent: AdapterView<*>?) {
showToast(activity,"nothing selected ",3)
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when (parent?.id) {
1 -> {productPosition = position
showToast(message ="product list")
}
else -> {dishPosition = position
showToast(message = "dish list")
}
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view: View = inflater.inflate(R.layout.fragment_add, container, false)
/** initialize ui with viewmodel*/
fun initializeUi() {
// Get the AddViewModelFactory with all of it's dependencies constructed
val factory = InjectorUtils.provideAddViewModelFactory()
// Use ViewModelProviders class to create / get already created AddViewModel
// for this view (activity)
val viewModel = ViewModelProviders.of(requireActivity(), factory)
.get(AddViewModel::class.java)
/** BINDERS FOR BUTTONS AND FIELDS */
val name = view.findViewById<EditText>(R.id.product_name).text
val price = view.findViewById<EditText>(R.id.product_price).text
val tax = view.findViewById<EditText>(R.id.product_tax).text
val waste = view.findViewById<EditText>(R.id.product_waste).text
val weightOfAddedProduct = view.findViewById<EditText>(R.id.product_weight)
val addButton = view.findViewById<Button>(R.id.addProduct)
val createDishButton = view.findViewById<Button>(R.id.new_dish_button)
val addProductToDishBtn = view.findViewById<ImageButton>(R.id.add_product_to_dish)
/** ADAPTERs FOR SPINNERs */
var productAdapter = ArrayAdapter(requireActivity(),android.R.layout.simple_spinner_item,viewModel.getProducts().value!!.map { it.name })
productAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
val mySpinner = view.findViewById<Spinner>(R.id.mySpinner)
with(mySpinner)
{
adapter = productAdapter
setSelection(0, false)
onItemSelectedListener = this@Add
prompt = "Select product"
gravity = Gravity.CENTER
}
mySpinner.id = NEW_SPINNER_ID
var dishesAdapter = ArrayAdapter(requireActivity(),android.R.layout.simple_spinner_item,viewModel.getDishes().value!!.map{it.name})
dishesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
val dishSpinner = view.findViewById<Spinner>(R.id.dishSpinner)
with(dishSpinner){
adapter = dishesAdapter
setSelection(0,false)
onItemSelectedListener = this@Add
prompt = "Select dish"
gravity = Gravity.CENTER
}
dishSpinner.id = ANOTHER_SPINNER_ID
/**OBSERVING LIVEDATA FROM ADDVIEWMODEL
* WHICH OBSERVES LIVEDATA IN REPOSITORY
* WHICH OBSERVES LIVEDATA FROM DAO */
viewModel.getProducts().observe(this, Observer { products ->
productAdapter.clear()
products.forEach { product ->
productAdapter.add(product.name)
}
})
viewModel.getDishes().observe(this, Observer { dishes ->
dishesAdapter.clear()
dishes.forEach{dish ->
dishesAdapter.add(dish.name)
}
})
/** BUTTONS FUNCTIONALITY */
createDishButton.setOnClickListener{
CreateDish().show(childFragmentManager,CreateDish.TAG)
}
addButton.setOnClickListener{
if(name.isNullOrEmpty()||
price.isNullOrEmpty()||
tax.isNullOrEmpty()||
waste.isNullOrEmpty()){showToast(message = "Fill all data!")}
else {
val product = Product(
name.toString(),
price.toString().toDouble(),
tax.toString().toDouble(),
waste.toString().toDouble()
)
viewModel.addProducts(product)
name.clear()
price.clear()
tax.clear()
waste.clear()
}
}
addProductToDishBtn.setOnClickListener{
val pickedDish = viewModel.getDishes().value!![this!!.dishPosition!!]
val pickedProduct = viewModel.getProducts().value!![this!!.productPosition!!]
viewModel.addProductToDish(pickedDish,pickedProduct,weightOfAddedProduct.text.toString().toDouble())
}
}
initializeUi()
return view
}
companion object {
fun newInstance():Add = Add()
const val TAG = "Add"
}
答案 0 :(得分:1)
我想我明白这个问题了。 因此,成功添加产品后,您将返回到片段编号 1(产品列表)。新产品在那里,太好了。 现在您将返回到第三个片段(添加产品),期望表单仍被填充(编辑文本字段等),但它们是空白的。
这样做的原因是第二次返回到第 3 个片段时,再次调用 onCreateView
并重新创建整个片段。在此 initializeUi
方法中,您没有填充文本字段(它不会记住您上次使用此片段时的值)。
您需要根据视图模型中的数据填充 EditText
方法中的 initializeUi
字段。
val name = view.findViewById<EditText>(R.id.product_name).text
name.text = viewModel.someLiveDataField.value
更新:
尝试从这些行的末尾删除 .text
(并重命名它们):
val nameEditText = view.findViewById<EditText>(R.id.product_name)
val priceEditText = view.findViewById<EditText>(R.id.product_price)
val taxEditText = view.findViewById<EditText>(R.id.product_tax)
val wasteEditText = view.findViewById<EditText>(R.id.product_waste)
现在,在您的 OnClickListener
中,将其更改为:
val product = Product(
nameEditText.text,
priceEditText.text.toDouble(),
taxEditText.text.toDouble(),
wasteEditText.text.toDouble()
)
(如果语法稍有错误,请见谅)。