将详细信息加载到片段中会导致操作未实现错误

Loading details into fragment causes An operation is not implemented error

我在片段控制器中有这段代码,所有运行正常,直到

crimeDetailViewModel.loadCrime(crimeId)

这会产生这个错误

kotlin.NotImplementedError: An operation is not implemented: Not yet implemented at com.bignerdranch.android.criminalintent.CrimeFragment$onStart$titleWatcher.beforeTextChanged(CrimeFragment.kt:116)

我以为是关于 ViewModel 版本的,因为我是这样连接的

private val crimeDetailViewModel : CrimeDetailViewModel by lazy { ViewModelProvider(this).get(CrimeDetailViewModel::class.java) }

但我使用犯罪列表的方式相同,它会根据需要提取数据

private val crimeListViewModel: CrimeListViewModel by lazy { ViewModelProvider(this).get(CrimeListViewModel::class.java) }

→ I/CrimeListFragment: Got Crimes 100

我试过调试它。我发现它可以正确获取 crimeID……但是使用加载函数 crimeDetailViewModel.loadCrime(crimeId) 显示犯罪会产生该错误……


import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.CheckBox
import android.widget.EditText
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.bignerdranch.android.criminalintent.database.CrimeDetailViewModel
import java.util.*
import androidx.lifecycle.Observer

private const val ARG_CRIME_ID = "crime_id"
class CrimeFragment: Fragment() {
    private lateinit var crime: Crime
    private lateinit var titleField: EditText
    private lateinit var dateButton: Button
    private lateinit var solvedCheckBox: CheckBox
   
    private val crimeDetailViewModel : CrimeDetailViewModel by lazy {
        ViewModelProvider(this).get(CrimeDetailViewModel::class.java)
    }

  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        crime = Crime()
        
        val crimeId: UUID = arguments?.getSerializable(ARG_CRIME_ID) as UUID
       
        crimeDetailViewModel.loadCrime(crimeId)  <--- this line is where the app crash
    }

  
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_crime, container,false)

        titleField = view.findViewById(R.id.crime_title) as EditText
        dateButton = view.findViewById(R.id.crime_date) as Button
        solvedCheckBox = view.findViewById(R.id.crime_solved) as CheckBox

        dateButton.apply {
            text = crime.date.toString()
            isEnabled = false
        }

        return view
    }

  
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        crimeDetailViewModel.crimeLiveData.observe(
            viewLifecycleOwner,
            Observer { crime ->
                crime?.let {
                    this.crime = crime
                    updateUI()
                }
            }
        )
    }

    override fun onStart() {
        super.onStart()
       
        val titleWatcher = object : TextWatcher{
            override fun beforeTextChanged(s: CharSequence?,
                                           start: Int,
                                           count: Int,
                                           after: Int) {
                TODO("Not yet implemented")  <-- error points to this line
            }

            override fun onTextChanged(s: CharSequence?,
                                       start: Int,
                                       before: Int,
                                       count: Int) {
                crime.title = s.toString()
            }

            override fun afterTextChanged(s: Editable?) {
                TODO("Not yet implemented")
            }
        }
        titleField.addTextChangedListener(titleWatcher)

        solvedCheckBox.apply {
            setOnCheckedChangeListener { _, isChecked ->
                crime.isSolved = isChecked
            }
        }
    }

    
    private fun updateUI() {
        titleField.setText(crime.title)
        dateButton.text = crime.date.toString()
        solvedCheckBox.isChecked = crime.isSolved
    }

    
    companion object{
        fun newInstance(crimeId: UUID):CrimeFragment{
            val args = Bundle().apply{
                putSerializable(ARG_CRIME_ID,crimeId)
                /* we can pass any argument and put it in Bundle,
                using the instance from parent activity
                 */
            }
            return CrimeFragment().apply {
                arguments = args
            }
        }
    }

   override fun onStop() {
        super.onStop()
        crimeDetailViewModel.saveCrime(crime)
    }
}

TODO 函数抛出 NotImplementedError。参见 https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-t-o-d-o.html。只需删除 TODO 功能,它就不会崩溃。这些功能是默认添加的,用于提醒您实现该方法。不过,在这种情况下,该回调无事可做,因此您只需将其从该方法和您打算留空的任何其他方法中删除即可。

        val titleWatcher = object : TextWatcher {
            override fun beforeTextChanged(
                s: CharSequence,
                start: Int,
                count: Int,
                after: Int
            ) = Unit

            override fun onTextChanged(
                s: CharSequence?,
                start: Int,
                before: Int,
                count: Int
            ) {
                crime.title = s.toString()
            }

            override fun afterTextChanged(s: Editable) = Unit
        }