帮助我理解为什么按下手机的“返回”按钮时数据重复,即我们有一个12个字段的列表,当从主片段移动到子片段再返回时,列表已经有24个字段,我们重复相同的步骤和列表已经是36个字段,等等现在也许记忆不会结束。
英雄碎片
class HeroesFragment : Fragment() {
private var mBinding: FragmentHeroesBinding? = null
private lateinit var mAllInfoApex: HeroesViewModel
private lateinit var mHeroesAdapter: HeroesAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
mBinding = FragmentHeroesBinding.inflate(inflater, container, false)
return mBinding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mAllInfoApex =
ViewModelProvider(this).get(HeroesViewModel::class.java)
mAllInfoApex.getAllInfoApexFromAPI(Constants.API_PLAYER_VALUE)
mBinding?.rvHeroList?.layoutManager = GridLayoutManager(requireActivity(), 2)
mHeroesAdapter = HeroesAdapter(this@HeroesFragment)
mBinding?.rvHeroList?.adapter = mHeroesAdapter
InfoApexViewModelObserver()
}
fun heroesDetails(legends: Heroes){
findNavController().navigate(HeroesFragmentDirections.actionAllHeroesToHeroesDetails(legends))
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_profile, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onDestroy() {
super.onDestroy()
mBinding = null
}
}
详情英雄片段
class DetailsHeroesFragment : Fragment() {
private var mBinding: FragmentDetailsHeroesBinding? = null
//private val hero : ArrayList<AllHeroes.Data>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mBinding = FragmentDetailsHeroesBinding.inflate(inflater, container, false)
// Inflate the layout for this fragment
return mBinding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val args: DetailsHeroesFragmentArgs by navArgs()
Glide.with(this)
.load(args.heroesDetails.data.ImgAssets.banner)
.into(mBinding!!.ivHeroesDetails)
mBinding!!.tvHeroesName.text = args.heroesDetails.name
args.heroesDetails.data.let { values ->
when {
values.data.isNullOrEmpty() -> {
mBinding!!.tvDataName.text = "NOT DATA"
mBinding!!.tvDataValue.visibility = View.INVISIBLE
mBinding!!.tvDataName2.visibility = View.INVISIBLE
mBinding!!.tvDataValue2.visibility = View.INVISIBLE
mBinding!!.tvDataName3.visibility = View.INVISIBLE
mBinding!!.tvDataValue3.visibility = View.INVISIBLE
mBinding!!.tvDataName4.visibility = View.INVISIBLE
mBinding!!.tvDataValue4.visibility = View.INVISIBLE
Log.i("Heroes test", "test")
}
else -> {
mBinding!!.tvDataName.visibility = View.INVISIBLE
mBinding!!.tvDataValue.visibility = View.INVISIBLE
mBinding!!.tvDataName2.visibility = View.INVISIBLE
mBinding!!.tvDataValue2.visibility = View.INVISIBLE
mBinding!!.tvDataName3.visibility = View.INVISIBLE
mBinding!!.tvDataValue3.visibility = View.INVISIBLE
mBinding!!.tvDataName4.visibility = View.INVISIBLE
mBinding!!.tvDataValue4.visibility = View.INVISIBLE
}
}
}
}
override fun onDestroy() {
super.onDestroy()
mBinding = null
}
}
主要活动
class MainActivity : AppCompatActivity() {
private lateinit var mBinding: ActivityMainBinding
private lateinit var mNavController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(mBinding.root)
mNavController = findNavController(R.id.nav_host_fragment_activity_main)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_all_heroes,
R.id.navigation_match_history,
R.id.navigation_funny_videos
)
)
setupActionBarWithNavController(mNavController, appBarConfiguration)
mBinding.navView.setupWithNavController(mNavController)
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(mNavController, null)
}
}
也就是说,当我从DetailsHeroesFragment返回到HeroesFragment时,会在现有数据中添加一列完全相同的数据,如何解决这个问题?或者我在哪里错过了什么?在日志中,我看到数据是如何创建 2 次的,然后在转换期间又是 +2 次,等等。
视图模型
class HeroesViewModel: ViewModel() {
private val allInfoApexAPIService = AllInfoApexAPIService()
private val compositeDisposable = CompositeDisposable()
val loadAllInfoApex = MutableLiveData<Boolean>()
val allInfoApexResponse = MutableLiveData<AllHeroes.Heroes>()
val allInfoApexLoadingError = MutableLiveData<Boolean>()
fun getAllInfoApexFromAPI(username: String){
loadAllInfoApex.value = true
compositeDisposable.add(
allInfoApexAPIService.getAllInfoApexTracker(player = username)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object: DisposableSingleObserver<AllHeroes.Heroes>(){
override fun onSuccess(value: AllHeroes.Heroes) {
loadAllInfoApex.value = false
allInfoApexResponse.value = value
allInfoApexLoadingError.value = false
}
override fun onError(e: Throwable) {
loadAllInfoApex.value = false
allInfoApexLoadingError.value = true
e.printStackTrace()
}
})
)
}
}
当你转到第二个fragment时,第一个fragment中的View被销毁,当你返回第一个fragment时,又重新创建了View,它们分别称为
onCreateView
、onViewCreated
和mAllInfoApex.getAllInfoApexFromAPI
。大概就是这种情况。一种解决方案是将调用移动getAllInfoApexFromAPI
到init
块ViewModel