保留旧信息的片段(未正确更新)



我正在Kotlin中开发一个应用程序,当涉及到我的一个名为ChartsFragment的特定片段时,我遇到了一些问题。基本上,当点击导航抽屉项目时,我会从数据库中查询数据,并将其传递给一个名为ChartsFragment的片段来显示。我正在使用Graph View在片段上绘制我的数据。现在,一切都很好,只是出于某种原因,我不得不点击两次片段的导航图标来加载更新的数据。当单击导航图标一次时,它不会更新数据。

这里有一个全局变量,用于存储来自数据库查询的数据:

private var completed = mutableListOf<String>()

以下是我从数据库查询数据时的代码:

/**
* For firebase database
* Read user progress from db
*/
private fun getProgress() {
val uid = FirebaseAuth.getInstance().getCurrentUser()?.uid
val rootRef = FirebaseDatabase.getInstance().getReference()
val progressRef = rootRef.child("Users").child(uid!!).child("Progress")
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot:DataSnapshot) {
for(dSnapshot : DataSnapshot in dataSnapshot.getChildren()) {
for(ds : DataSnapshot in dSnapshot.getChildren()) {
val key = ds.getKey() as String
completed.add(key)
Log.d(TAG2, key)
}
}
}
override fun onCancelled(@NonNull databaseError : DatabaseError) {
Log.d(TAG2, databaseError.getMessage())
}
}
progressRef.addListenerForSingleValueEvent(valueEventListener)
}

这是我点击导航抽屉图标Charts时的代码:

R.id.nav_chart -> {
val currentUser = mAuth!!.currentUser
if (currentUser != null) {
getProgress()
var basics = 0
var loops = 0
var functions = 0
completed.forEach {
if (it == "Data Type" || it == "Operation" || it == "Condition" || it == "Null Safety") {
basics++
} else if (it == "For" || it == "Break" || it == "Repeat" || it == "When" || it == "While") {
loops++
} else if (it == "Call" || it == "Main" || it == "Recursion" || it == "Single Expression") {
functions++
}
}
completed.clear()
val bundle = Bundle()
bundle.putDouble("basics",basics.toDouble())
bundle.putDouble("loops",loops.toDouble())
bundle.putDouble("functions",functions.toDouble())
chartFragment(bundle)
} else {
Toast.makeText(applicationContext, R.string.sign_in_to_track, Toast.LENGTH_SHORT).show()
}
}

以下是我加载片段时的代码:

/**
* For loading fragments
*/
fun chartFragment(bundle: Bundle){
this.setTitle(R.string.navigation_drawer_chart)
val fragmentManager = supportFragmentManager
val transaction = fragmentManager.beginTransaction()
val fragment = ChartFragment()
fragment.setArguments(bundle)
transaction.replace(R.id.frameLayout1, fragment)
transaction.commit()
}

这是我的碎片的onCreateView:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_chart, container, false)
val graph = view?.findViewById(R.id.graph) as GraphView
val basics = arguments!!.getDouble("basics")
val loops = arguments!!.getDouble("loops")
val functions  = arguments!!.getDouble("functions")
val series = LineGraphSeries(arrayOf(
DataPoint(0.0, 0.0),
DataPoint(1.0, basics),
DataPoint(2.0, loops),
DataPoint(3.0, functions),
DataPoint(4.0, 0.0)
))
series.setColor(Color.GREEN)
series.setDrawDataPoints(true)
series.setAnimated(true)
graph.addSeries(series)
return view
}

我想这是缓存问题吗?有没有一种方法可以强制点击导航抽屉的项目作为临时解决方案?

更新:我想AsyncTasks可能会解决这个问题,但我不知道如何实现AsyncTasks任务。似乎最可能的原因是getProgress()可能太慢,程序正在执行下一行,而不是等待getProgress()完成。

更新:第一次点击后我得到的completed的大小总是上一次点击的大小(不是来自数据库的更新数据(,第二次点击时,我会得到当前大小(来自数据库的当前大小(。因此,如果我的数据库有0个项目,在第一次点击时,我会得到0,这是正确的,那么如果我在应用程序中完成了一个活动,数据库就会更新为1个项目。所以,如果我现在点击图表图标,我应该得到1号,但我得到的是0号。第二次点击,我会得到1号。

更新:因此,如果我在应用程序中完成另一项活动,我的数据库现在应该有2个项目。所以,如果我再次单击图表图标,我应该得到2号,但我不会仍然停留在以前的1号。我第二次点击这个,我会得到2号的。

似乎最可能的原因是getProgress((可能太慢,程序正在执行下一行,而不是等待getProgress(完成。

是的,在完成更新之前,程序正在执行getProgress()之后的下一行。但实际上getProgress()已经完成了。它的工作只是触发数据库调用。调用本身是异步执行的(即在另一个线程上(。一旦执行了onDataChange(),主线程就可以访问结果。这只能在当前运行的功能(处理图标单击的功能(完成后发生。

由于您的逻辑取决于数据库调用的结果,因此应该将计算新数据的行移到onDataChange()

最新更新