Я пытаюсь создать приложение, которое перечисляет кучу преступлений из базы данных с использованием комнаты, приложение находится в двух фрагментах < /p>
Перечисляет преступления (преступления CrimelistFragment) < /li>
См. AD. Изменить подробности о совершенном преступлении (CrimedetailFragment) делать, но для странной ошибки я не могу обойтись. Когда преступление нажимается, и перемещается в фрагмент редактирования, пользователь редактирует свойства класса через пользовательский интерфейс, а новые данные обновляются в базе данных, но когда пользователь нажимает обратно, чтобы вернуться в фрагмент списка, изменения не видно в Fragment UI списка. Но если я снова нажму то же преступление, перейдите к фрагменту детализации преступления и снова перейдите к фрагменту листинга, изменения обновляются в пользовательском интерфейсе. Я считаю, что состояние обновляется, когда эта часть наблюдается с использованием Livedata и Coroutines. Что я хочу знать, так это то, почему пользовательский интерфейс не обновляется без странных туда -сюда. Я попытался использовать функцию задержки в методе Frecate Fragment List, чтобы укрепить время приложения для обновления состояния, и пользовательский интерфейс, в том числе Livedata, просто занимал немного времени (это случалось со мной раньше), но функция задержки не имеет Задержка, независимо от того, в какую область я вкладываю.
package com.andpro.android.criminalintent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.andpro.android.criminalintent.databinding.FragmentCrimeListBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class CrimeListFragment : Fragment() {
private var _binding: FragmentCrimeListBinding? = null
private val binding: FragmentCrimeListBinding
get() {
return _binding!!
}
lateinit private var CVM: CrimeListViewModel
private var job: Job = Job()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
CVM = ViewModelProvider(this).get(CrimeListViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentCrimeListBinding.inflate(inflater, container, false)
val root_view: View = binding.root
job = viewLifecycleOwner.lifecycleScope.launch {
CVM.initialize_crimes()
}
CVM.crimes.observe(viewLifecycleOwner) { newValue ->
binding.recycler.adapter = CrimeListAdapter(newValue, { crime_id ->
findNavController().navigate(
CrimeListFragmentDirections.actionCrimeListFragmentToCrimeDetailFragment(
crime_id
)
)
})
}
return root_view
}
override fun onStart() {
viewLifecycleOwner.lifecycleScope.launch {
delay(5000)
}
super.onStart()
}
override fun onStop() {
super.onStop()
job?.cancel()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
< /code>
----------------- CreamedetailFragment < /p>
package com.andpro.android.criminalintent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.andpro.android.criminalintent.databinding.FragmentCrimeDetailBinding
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Date
import java.util.UUID
class CrimeDetailFragment : Fragment() {
private var _binding: FragmentCrimeDetailBinding? = null
private val binding: FragmentCrimeDetailBinding
get() {
return _binding!!
}
private var job: Job? = Job()
lateinit private var CDVM: CrimeDetailViewModel
private var updated_crime: CrimeClass = CrimeClass(UUID.randomUUID(), "", Date(), false)
private var crime_id: UUID = UUID.randomUUID()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
CDVM = ViewModelProvider(this).get(CrimeDetailViewModel::class.java)
crime_id = CrimeDetailFragmentArgs.fromBundle(requireArguments()).crimeId
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentCrimeDetailBinding.inflate(inflater, container, false)
val root_view: View = binding.root
return root_view
}
fun update_ui(crime: CrimeClass?) {
binding.crimeTitle.setText(crime!!.title)
binding.crimeDate.setText(crime.date.toString())
binding.crimeSolved.isChecked = crime.isSolved
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
CDVM.initialize_crime(crime_id)
CDVM.current_crime.observe(viewLifecycleOwner) { newValue ->
update_ui(newValue)
}
binding.crimeTitleAdd.doOnTextChanged { text, _, _, _ ->
binding.savechangebutton.visibility = View.VISIBLE
CDVM.updateCrime(
requireNotNull(CDVM.current_crime.value),
_title = text.toString(),
_isSolved = requireNotNull(CDVM.current_crime.value).isSolved
)
}
binding.crimeSolved.setOnCheckedChangeListener { _, isChecked ->
CDVM.updateCrime(
requireNotNull(CDVM.current_crime.value),
_isSolved = isChecked,
_title = requireNotNull(CDVM.current_crime.value).title
)
}
binding.savechangebutton.setOnClickListener {
updated_crime = requireNotNull(CDVM.current_crime.value)
CDVM.updateCrime(updated_crime, updated_crime.title, updated_crime.isSolved)
Toast.makeText((activity as AppCompatActivity), "Updating list...", Toast.LENGTH_LONG)
.show()
}
navigating")
}
override fun onStop() {
super.onStop()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
< /code>
-------------------------- CumedetailViewModel < /p>
package com.andpro.android.criminalintent
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import java.util.UUID
class CrimeDetailViewModel : ViewModel() {
private val crimeRepo = CrimeRepository.get()
private val crime: MutableLiveData = MutableLiveData()
val current_crime: MutableLiveData
get() {
return crime
}
fun initialize_crime(id: UUID) {
viewModelScope.launch {
crime.value = crimeRepo.getCrime(id)
}
}
fun updateCrime(Crime: CrimeClass, _title: String = "", _isSolved: Boolean = false) {
current_crime.value = Crime.copy(title = _title, isSolved = _isSolved)
}
override fun onCleared() {
super.onCleared()
Log.i("CDVM", "${current_crime.value?.title}")
crimeRepo.updateTitle(
requireNotNull(current_crime.value?.id),
requireNotNull(current_crime.value?.title)
)
crimeRepo.updateDate(
requireNotNull(current_crime.value?.id),
requireNotNull(current_crime.value?.date)
)
crimeRepo.updateSolvedStatus(
requireNotNull(current_crime.value?.id),
requireNotNull(current_crime.value?.isSolved)
)
}
}
< /code> ------------------ CrimalistViewModel < /p>
package com.andpro.android.criminalintent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class CrimeListViewModel : ViewModel() {
private val crimeRepo = CrimeRepository.get()
suspend fun initialize_crimes() {
viewModelScope.launch {
_crimes.value = crimeRepo.getCrimes()
}
}
private val _crimes: MutableLiveData = MutableLiveData()
val crimes: MutableLiveData
get() {
return _crimes
}
}
< /code>
--------- Crimerepository < /p>
package com.andpro.android.criminalintent
import android.content.Context
import androidx.room.Room
import com.andpro.android.criminalintent.database.CrimeDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.Date
import java.util.UUID
class CrimeRepository private constructor(context: Context) {
private val coroutineScope: CoroutineScope = GlobalScope
private val database: CrimeDatabase = Room.databaseBuilder(
klass = CrimeDatabase::class.java,
context = context.applicationContext,
name = "Crime Database"
).createFromAsset("crime-database")
.build()
companion object {
private var INSTANCE: CrimeRepository? = null
fun initialize(context: Context) {
if (INSTANCE == null) {
INSTANCE = CrimeRepository(context)
}
}
fun get(): CrimeRepository {
return INSTANCE ?: throw IllegalStateException("You must initialize
the repo first")
}
}
suspend fun getCrimes(): List = database.crimeDao().getCrimes()
suspend fun getCrime(id: UUID): CrimeClass = database.crimeDao().getCrime(id)
fun updateTitle(crime_id: UUID, newTitle: String) {
coroutineScope.launch {
database.crimeDao().updateTitle(crime_id, newTitle)
}
}
fun updateDate(crime_id: UUID, newDate: Date) {
coroutineScope.launch {
database.crimeDao().updateDate(crime_id, newDate)
}
}
fun updateSolvedStatus(crime_id: UUID, isSolved: Boolean) {
coroutineScope.launch {
database.crimeDao().updateSolvedStatus(crime_id, isSolved)
}
}
}
< /code>
------------------- Дао (при необходимости) < /p>
package com.andpro.android.criminalintent.database
import androidx.room.Dao
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.andpro.android.criminalintent.CrimeClass
import java.util.Date
import java.util.UUID
@Dao
interface CrimeDao {
@Query("SELECT * FROM crime")
suspend fun getCrimes(): List
@Query("UPDATE crime SET title = :newTitle WHERE id = :crime_id")
suspend fun updateTitle(crime_id: UUID, newTitle: String)
@Query("UPDATE crime SET date = :newDate WHERE id = :crime_id")
suspend fun updateDate(crime_id: UUID, newDate: Date)
@Query("UPDATE crime SET isSolved = :newIsSolved WHERE id = :crime_id")
suspend fun updateSolvedStatus(crime_id: UUID, newIsSolved: Boolean)
@Query("SELECT * FROM crime WHERE id=(:id)")
suspend fun getCrime(id: UUID): CrimeClass
}
p.s Причина, по которой я использовал аннотации запросов для обновлений, заключалась в том, что компилятор давал мне странную ошибку каждый раз, когда я использовал аннотации обновления
Я пытаюсь создать приложение, которое перечисляет кучу преступлений из базы данных с использованием комнаты, приложение находится в двух фрагментах < /p>
Перечисляет преступления (преступления CrimelistFragment) < /li> См. AD. Изменить подробности о совершенном преступлении (CrimedetailFragment) делать, но для странной ошибки я не могу обойтись. Когда преступление нажимается, и перемещается в фрагмент редактирования, пользователь редактирует свойства класса через пользовательский интерфейс, а новые данные обновляются в базе данных, но когда пользователь нажимает обратно, чтобы вернуться в фрагмент списка, изменения не видно в Fragment UI списка. Но если я снова нажму то же преступление, перейдите к фрагменту детализации преступления и снова перейдите к фрагменту листинга, изменения обновляются в пользовательском интерфейсе. Я считаю, что состояние обновляется, когда эта часть наблюдается с использованием Livedata и Coroutines. Что я хочу знать, так это то, почему пользовательский интерфейс не обновляется без странных туда -сюда. Я попытался использовать функцию задержки в методе Frecate Fragment List, чтобы укрепить время приложения для обновления состояния, и пользовательский интерфейс, в том числе Livedata, просто занимал немного времени (это случалось со мной раньше), но функция задержки не имеет Задержка, независимо от того, в какую область я вкладываю.[code] package com.andpro.android.criminalintent
@Dao interface CrimeDao { @Query("SELECT * FROM crime") suspend fun getCrimes(): List
@Query("UPDATE crime SET title = :newTitle WHERE id = :crime_id") suspend fun updateTitle(crime_id: UUID, newTitle: String)
@Query("UPDATE crime SET date = :newDate WHERE id = :crime_id") suspend fun updateDate(crime_id: UUID, newDate: Date)
@Query("UPDATE crime SET isSolved = :newIsSolved WHERE id = :crime_id") suspend fun updateSolvedStatus(crime_id: UUID, newIsSolved: Boolean)
@Query("SELECT * FROM crime WHERE id=(:id)") suspend fun getCrime(id: UUID): CrimeClass
} [/code] p.s Причина, по которой я использовал аннотации запросов для обновлений, заключалась в том, что компилятор давал мне странную ошибку каждый раз, когда я использовал аннотации обновления