为什么按钮点击发生两次在这个应用程序?



我有一个应用程序,其中一个功能是你可以通过点击它的cardview来选择一周中的一天。

我目前的问题是,如果你执行以下顺序,你会得到一个意想不到的结果:

明确→采摘日->添加任务->提交→主活动的返回按钮

当您执行此顺序时,数据库会在初始清除之后意外地再次清除,或者如果您转到某一天,添加任务并导航回来,它会再次运行并且/或将您放回到您刚刚离开的那一天的视图中。

我注意到的和我尝试过的:

我的foreach循环做了它应该做的事情:翻遍工作日,直到它遇到正确的…然后它又会这样做?我知道它从日志和Toast中发生了太多,在它完成后再次弹出(它说db自动清除,然后是,没有什么要清除)。此外,我试图在foreach循环中添加断点,但我不认为这对我有帮助,因为它只会打破循环的迭代,如果我没有弄错的话?

我已经尝试了一个活动级别布尔变量,使它在我需要的时候停止和开始,但问题最终是,我要么需要按任何给定的卡两次,它在选择第一个项目后根本不做任何事情,或者问题保持不变。

我在xml中使用onClick作为按钮侦听器,但我也尝试将其编程到活动kotlin类中,它没有产生差异

也许我只是在某个地方错过了一个额外的循环迭代,或者在适当的地方中断?

主活动XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="@+id/top_box"
android:layout_width="0dp"
android:layout_height="90dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.card.MaterialCardView
android:id="@+id/clear_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@id/top_box"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/sunday_card"
app:layout_constraintBottom_toTopOf="@id/wednesday_card">
<TextView
android:id="@+id/clear_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"
/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/sunday_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@+id/top_box"
app:layout_constraintLeft_toRightOf="@id/clear_card"
app:layout_constraintRight_toLeftOf="@id/monday_card"
app:layout_constraintBottom_toTopOf="@id/thursday_card">
<TextView
android:id="@+id/sunday_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/monday_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@id/top_box"
app:layout_constraintLeft_toRightOf="@id/sunday_card"
app:layout_constraintRight_toLeftOf="@id/tuesday_card"
app:layout_constraintBottom_toTopOf="@id/friday_card">
<TextView
android:id="@+id/monday_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/tuesday_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@id/top_box"
app:layout_constraintLeft_toRightOf="@id/monday_card"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/saturday_card">
<TextView
android:id="@+id/tuesday_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/wednesday_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@id/clear_card"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/thursday_card"
app:layout_constraintBottom_toTopOf="@id/bottom_box">
<TextView
android:id="@+id/wednesday_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/thursday_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@id/sunday_card"
app:layout_constraintLeft_toRightOf="@id/wednesday_card"
app:layout_constraintRight_toRightOf="@id/friday_card"
app:layout_constraintBottom_toTopOf="@id/bottom_box">
<TextView
android:id="@+id/thursday_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/friday_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@id/monday_card"
app:layout_constraintLeft_toRightOf="@id/thursday_card"
app:layout_constraintRight_toLeftOf="@id/saturday_card"
app:layout_constraintBottom_toTopOf="@id/bottom_box">
<TextView
android:id="@+id/friday_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
android:id="@+id/saturday_card"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:onClick="buttonClick"
app:layout_constraintTop_toBottomOf="@id/tuesday_card"
app:layout_constraintLeft_toRightOf="@id/friday_card"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_box">
<TextView
android:id="@+id/saturday_card_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20sp"
android:gravity="center"/>
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/bottom_box"
android:layout_width="0dp"
android:layout_height="90dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val plannerViewModel: PlannerViewModel by viewModels {
PlannerViewModelFactory((application as PlannerApplication).repository)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val clearButtonText = binding.clearCardText
val sundayButtonText = binding.sundayCardText
val mondayButtonText = binding.mondayCardText
val tuesdayButtonText = binding.tuesdayCardText
val wednesdayButtonText = binding.wednesdayCardText
val thursdayButtonText = binding.thursdayCardText
val fridayButtonText = binding.fridayCardText
val saturdayButtonText = binding.saturdayCardText
// Setting day card names
clearButtonText.text = "Clear"
sundayButtonText.text = "Sun"
mondayButtonText.text = "Mon"
tuesdayButtonText.text = "Tue"
wednesdayButtonText.text = "Wed"
thursdayButtonText.text = "Thu"
fridayButtonText.text = "Fri"
saturdayButtonText.text = "Sat"
sundayButtonText.text = "Sun"
}
private fun startWeekdayActivity(day: Weekday) {
val intent = Intent(this, WeekdayActivity::class.java)
intent.putExtra("dayId", day.id)
this.startActivity(intent)
}
private fun clearDb() {
val alertDialog: AlertDialog? = this?.let { outerIt ->
val builder = AlertDialog.Builder(outerIt)
builder.apply {
setPositiveButton("Clear",
DialogInterface.OnClickListener { dialog, id ->
plannerViewModel.allTasks.observe(outerIt, {
if (it.count() == 0) {
Toast.makeText(context, "No tasks to clear", Toast.LENGTH_SHORT).show()
}
else {
plannerViewModel.deleteAllTasks()
Toast.makeText(context, "Tasks cleared", Toast.LENGTH_SHORT).show()
}
})
})
setNegativeButton("Cancel",
DialogInterface.OnClickListener { dialog, id ->
// User cancelled the dialog
})
}
.setTitle("Clear tasks?")
.setMessage("Are you sure you want to clear the weeks tasks?")
// Create the AlertDialog
builder.create()
}
alertDialog?.show()
}
private fun checkDay(dayIn: String) {
var dayOut: Weekday? = null
plannerViewModel.allWeekdays.observe(this, { weekdays ->
weekdays?.let {
weekdays.forEach {
if (dayIn == "clear_card" && it.day == "Clear") {
clearDb()
dayOut = it
}
else {
val dayInAbr = dayIn.substring(0, 3).toLowerCase(Locale.ROOT)
val dayOutAbr = it.day.substring(0,3).toLowerCase(Locale.ROOT)
if (dayInAbr == dayOutAbr) {
dayOut = it
dayOut?.let { startWeekdayActivity(it) }
}
}
if (dayOut != null) {
return@let
}
}
}
})
}
fun buttonClick(view: View) {
when(view.id) {
R.id.clear_card -> checkDay(view.context.resources.getResourceEntryName(R.id.clear_card).toString())
R.id.sunday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.sunday_card).toString())
R.id.monday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.monday_card).toString())
R.id.tuesday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.tuesday_card).toString())
R.id.wednesday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.wednesday_card).toString())
R.id.thursday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.thursday_card).toString())
R.id.friday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.friday_card).toString())
R.id.saturday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.saturday_card).toString())
}
}
}

Jay在评论中回答的问题

如果你知道一种方法让我把他们的分数和声誉归功于他们,请告诉我!

我需要停止调用更多的观察者实例每次checkDay()运行。移动观察者到onCreate(),这样他们只运行一次似乎已经解决了我的问题!

主活动工作代码

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val plannerViewModel: PlannerViewModel by viewModels {
PlannerViewModelFactory((application as PlannerApplication).repository)
}
lateinit var weekdayList: List<Weekday>
lateinit var taskList: List<Task>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val clearButtonText = binding.clearCardText
val sundayButtonText = binding.sundayCardText
val mondayButtonText = binding.mondayCardText
val tuesdayButtonText = binding.tuesdayCardText
val wednesdayButtonText = binding.wednesdayCardText
val thursdayButtonText = binding.thursdayCardText
val fridayButtonText = binding.fridayCardText
val saturdayButtonText = binding.saturdayCardText
// Setting day card names
clearButtonText.text = "Clear"
sundayButtonText.text = "Sun"
mondayButtonText.text = "Mon"
tuesdayButtonText.text = "Tue"
wednesdayButtonText.text = "Wed"
thursdayButtonText.text = "Thu"
fridayButtonText.text = "Fri"
saturdayButtonText.text = "Sat"
sundayButtonText.text = "Sun"
plannerViewModel.allTasks.observe(this, {
taskList = it
})
plannerViewModel.allWeekdays.observe(this, {
weekdayList = it
})
}
private fun startWeekdayActivity(day: Weekday) {
val intent = Intent(this, WeekdayActivity::class.java)
intent.putExtra("dayId", day.id)
this.startActivity(intent)
}
private fun clearDb(taskList: List<Task>) {
val alertDialog: AlertDialog? = this?.let { outerIt ->
val builder = AlertDialog.Builder(outerIt)
builder.apply {
setPositiveButton("Clear",
DialogInterface.OnClickListener { dialog, id ->
if (taskList.count() == 0) {
Toast.makeText(context, "No tasks to clear", Toast.LENGTH_SHORT).show()
} else {
plannerViewModel.deleteAllTasks()
Toast.makeText(context, "Tasks cleared", Toast.LENGTH_SHORT).show()
}
})
setNegativeButton("Cancel",
DialogInterface.OnClickListener { dialog, id ->
// User cancelled the dialog
})
}
.setTitle("Clear tasks?")
.setMessage("Are you sure you want to clear the weeks tasks?")
builder.create()
}
alertDialog?.show()
}
private fun checkDay(dayIn: String, weekdayList: List<Weekday>) {
weekdayList.forEach {
if (dayIn == "clear_card" && it.day == "Clear") {
clearDb(taskList)
} else {
val dayInAbr = dayIn.substring(0, 3).toLowerCase(Locale.ROOT)
val dayOutAbr = it.day.substring(0, 3).toLowerCase(Locale.ROOT)
if (dayInAbr == dayOutAbr) {
startWeekdayActivity(it)
}
}
}
}
fun buttonClick(view: View) {
when (view.id) {
R.id.clear_card -> checkDay(view.context.resources.getResourceEntryName(R.id.clear_card).toString(), weekdayList)
R.id.sunday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.sunday_card).toString(), weekdayList)
R.id.monday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.monday_card).toString(), weekdayList)
R.id.tuesday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.tuesday_card).toString(), weekdayList)
R.id.wednesday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.wednesday_card).toString(), weekdayList)
R.id.thursday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.thursday_card).toString(), weekdayList)
R.id.friday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.friday_card).toString(), weekdayList)
R.id.saturday_card -> checkDay(view.context.resources.getResourceEntryName(R.id.saturday_card).toString(), weekdayList)
}
}
}

最新更新