我正在開發一個 TodoList 應用程式,如果一個或所有必填欄位為空,我將實施設定為不允許用戶添加任務。這個實作以前作業得很好。但是,當我最近遇到一些錯誤時,它神秘地停止了作業。當我第一次使它作業時,我已經重新檢查了所有內容,甚至是提交,我沒有看到任何區別,但它仍然無法正常作業。我謙虛地請您檢查我的實作是否正確,并建議如何正確處理此功能。這是我的代碼...
首先是我的模型
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.util.*
/** Our Model class. This class will represent our database table **/
@Entity(tableName = "todo_table")
data class Todo(
@PrimaryKey (autoGenerate = true) // here "Room" will autoGenerate the id for us instead of assigning a randomUUID value
val id : Int = 0,
var title : String = "",
var date : Date = Date(),
var time : Date = Date(),
var todoCheckBox : Boolean = false
)
添加片段
import android.graphics.Color
import android.os.Bundle
import android.text.SpannableString
import android.text.TextPaint
import android.text.TextUtils
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.bignerdranch.android.to_dolist.R
import com.bignerdranch.android.to_dolist.data.TodoViewModel
import com.bignerdranch.android.to_dolist.databinding.FragmentAddBinding
import com.bignerdranch.android.to_dolist.fragments.dialogs.DatePickerFragment
import com.bignerdranch.android.to_dolist.fragments.dialogs.TimePickerFragment
import com.bignerdranch.android.to_dolist.model.Todo
import java.text.SimpleDateFormat
import java.util.*
private const val DIALOG_DATE = "DialogDate"
private const val DIALOG_TIME = "DialogTime"
const val SIMPLE_DATE_FORMAT = "MMM, d yyyy"
const val SIMPLE_TIME_FORMAT = "H:mm"
private const val TAG = "AddFragment"
class AddFragment : Fragment() {
private lateinit var todoViewModel : TodoViewModel
private var _binding : FragmentAddBinding? = null
private val binding get() = _binding!!
private lateinit var todo : Todo
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
todo = Todo()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentAddBinding.inflate(inflater, container, false)
todoViewModel = ViewModelProvider(this)[TodoViewModel::class.java]
remindersTextSpan()
// will insert our database when clicked
binding.abCheckYes.setOnClickListener {
insertTodoInDatabase()
}
// showing our datePickerDialog
binding.edDate.setOnClickListener {
childFragmentManager.setFragmentResultListener("requestKey", viewLifecycleOwner)
{_, bundle ->
val result = bundle.getSerializable("bundleKey") as Date
// passing the result of the user selected date directly to the _Todo class instead
todo.date = result
// will ONLY update the date field when it is not empty so that we don't get a preloaded Date textView
if(todo.date.toString().isNotEmpty()) {
updateDate()
}
}
DatePickerFragment().show(this@AddFragment.childFragmentManager, DIALOG_DATE)
}
// showing our timePickerDialog
binding.edTime.setOnClickListener {
childFragmentManager.setFragmentResultListener("tRequestKey",
viewLifecycleOwner) {_, bundle ->
val result = bundle.getSerializable("tBundleKey") as Date
// passing the result of the user selected time directly to the _Todo class instead
todo.time = result
// will ONLY update the time field when it is not empty so that we don't get a preloaded Time textView
if (todo.time.toString().isNotEmpty()) {
updateTime()
}
}
TimePickerFragment().show(this@AddFragment.childFragmentManager, DIALOG_TIME)
}
return binding.root
}
// function to update Date
private fun updateDate() {
val dateLocales = SimpleDateFormat(SIMPLE_DATE_FORMAT, Locale.getDefault())
binding.edDate.text = dateLocales.format(todo.date)
}
// function to update Time
private fun updateTime() {
val timeLocales = SimpleDateFormat(SIMPLE_TIME_FORMAT, Locale.getDefault())
binding.edTime.text = timeLocales.format(todo.time)
}
// our reminders Text span
private fun remindersTextSpan() {
val spannableString = SpannableString("Set Reminders")
val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
Toast.makeText(context, "Set Reminders!", Toast.LENGTH_LONG).show()
}
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = Color.BLUE
}
}
spannableString.setSpan(clickableSpan, 0, 13,
SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
binding.tvReminders.text = spannableString
binding.tvReminders.movementMethod = LinkMovementMethod.getInstance()
}
// This function's job will be to insert Tasks in our database
private fun insertTodoInDatabase() {
val title = binding.edTaskTitle.text.toString()
val date = binding.edDate.text.toString()
val time = binding.edTime.text.toString()
if (inputCheck(title, date, time)) {
val todo = Todo(0, title)
todoViewModel.addTodo(todo)
// This will make a toast saying Successfully added task if we add a task
Toast.makeText(requireContext(), R.string.task_add_toast,
Toast.LENGTH_LONG).show()
// FIXME: There is a bug here that allows the user to add Todos even when some OR all of the fields are empty.
// FIXME: It has to do with updateTime and updateDate functions I think, so I will try to fix it but maybe not now.
findNavController().navigate(R.id.action_addFragment_to_listFragment)
} else {
Toast.makeText(requireContext(), R.string.no_task_add_toast,
Toast.LENGTH_LONG).show()
}
Log.d(TAG, "Our todo widgets are $title $date and $time")
}
// This function will help us check if the texts are empty and then proceed to add them to the database
// so that we do not add empty tasks to our database
private fun inputCheck(title : String, date: String, time: String) : Boolean {
// will return false if fields in TextUtils are empty and true if not
return !(TextUtils.isEmpty(title) && TextUtils.isEmpty(date) && time.isEmpty())
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
我的 DAO
/**
* This will be our DAO file where we will be update, delete and add Todos to our
database so it contains the methods used for accessing the database
*/
@Dao
interface TodoDao {
// onConflict will ignore any known conflicts, in this case will remove duplicate "Todos" with the same name
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addTodo(todo: Todo)
@Query("SELECT * FROM todo_table ORDER BY id ASC")
fun readAllData() : LiveData<List<Todo>>
@Query("DELETE FROM todo_table WHERE id IN (:idList)")
suspend fun deleteSelectedTasks(idList : Long)
@Query("DELETE FROM todo_table")
suspend fun deleteAllTasks()
}
這些是即使缺少一個也不應該添加的空串列,在這種情況下是標題。
然后這是我的除錯測驗,它證明任何嘗試的任務中的部分或全部欄位實際上是空的。在“和”之間有空格或只有日期或時間的除錯日志訊息證明部分或所有欄位為空,但仍會被添加。這之前作業得很好,我不知道為什么它停止了。
uj5u.com熱心網友回復:
我是這么認為的... inputCheck 方法出現錯誤。
將 and 運算子更改為 or 運算子。
前
// This function will help us check if the texts are empty and then proceed to add them to the database
// so that we do not add empty tasks to our database
private fun inputCheck(title : String, date: String, time: String) : Boolean {
// will return false if fields in TextUtils are empty and true if not
return !(TextUtils.isEmpty(title) && TextUtils.isEmpty(date) && time.isEmpty())
}
后
// This function will help us check if the texts are empty and then proceed to add them to the database
// so that we do not add empty tasks to our database
private fun inputCheck(title : String, date: String, time: String) : Boolean {
// will return false if fields in TextUtils are empty and true if not
return !(TextUtils.isEmpty(title) || TextUtils.isEmpty(date) || time.isEmpty())
}
添加評論。
'and' 運算子是所有值都必須為真。
'is' 運算子為真,即使只有一個值為真。
例如,欄位狀態。(標題為空,日期不為空,時間不為空。)
在方法步驟之前。
- !(TextUtils.isEmpty(title) && TextUtils.isEmpty(date) && time.isEmpty())
- !(真 && 假 && 假)
- !(錯誤的)
- 真的
在方法步驟之后。
- !(TextUtils.isEmpty(title) || TextUtils.isEmpty(日期) || time.isEmpty())
- !(真 || 假 || 假)
- !(真的)
- 錯誤的
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/488834.html