我對回收站的看法很奇怪。
這是我的片段,它具有回收者視圖:
class CarsListFragment : Fragment() {
private var _binding: FragmentCarsListBinding? = null
private val binding get() = _binding!!
private lateinit var carsListViewModel: CarsListViewModel
private lateinit var carsAdapter: CarsListAdapter
private val swipeCallback: ItemTouchHelper.SimpleCallback =
object: ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
carsAdapter.deleteCar(viewHolder.adapterPosition)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
carsListViewModel = ViewModelProvider(requireActivity(),
CarsListViewModelFactory(
CarsListRepository()
)
).get(CarsListViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentCarsListBinding.inflate(inflater, container, false)
binding.btnAddCar.setOnClickListener {
findNavController().navigate(CarsListFragmentDirections.actionCarsListFragmentToAddCarFragment())
}
carsAdapter = CarsListAdapter(::adapterDeleteCarCallback)
binding.rvCars.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = carsAdapter
}.also {
val itemTouchHelper = ItemTouchHelper(swipeCallback)
itemTouchHelper.attachToRecyclerView(it)
}
observeCarsData()
return binding.root
}
override fun onStart() {
super.onStart()
carsListViewModel.attachListener()
}
override fun onStop() {
super.onStop()
carsListViewModel.detachListener()
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
private fun observeCarsData() {
carsListViewModel.addedCar.observe(viewLifecycleOwner, { data ->
Log.d("CarsVM", "Car object added")
Log.d("CarsVM", "Car: $data")
data?.let {
carsAdapter.addCar(it)
}
})
}
private fun adapterDeleteCarCallback(id: String) {
carsListViewModel.removeCar(id)
}
這是我的視圖模型:
class CarsListViewModel(
private val repository: CarsListRepository
): ViewModel() {
val addedCar = repository.addedCar
fun removeCar(id: String) = repository.removeCar(id)
fun attachListener() = repository.addListener()
fun detachListener() = repository.removeListener()
}
這是我的存盤庫:
object CarsListRepository {
private val _firebaseAuth: FirebaseAuth by lazy { FirebaseAuth.getInstance() }
private var _dbCarsListReference: DatabaseReference = FirebaseDatabase.getInstance().getReference("users")
.child(_firebaseAuth.currentUser!!.uid)
.child("cars")
private var _addedCar = MutableLiveData<Car>()
val addedCar: LiveData<Car> get() = _addedCar
private val userCarsListener = object: ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
Log.d("Repo", "added car. Response: ${snapshot}")
snapshot.getValue(Car::class.java)?.let { car -> _addedCar.value = car }
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
TODO("Not yet implemented")
}
override fun onChildRemoved(snapshot: DataSnapshot) {
Log.d("Repo", "deleted car. Response: ${snapshot}")
}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
TODO("Not yet implemented")
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
}
operator fun invoke(): CarsListRepository {
return this
}
fun removeCar(carId: String) {
Log.d("Repo", "Passed ID: $carId")
_dbCarsListReference.child(carId).removeValue()
}
fun addListener() {
Log.d("Repo", "Listener added")
_dbCarsListReference.addChildEventListener(userCarsListener)
}
fun removeListener() {
Log.d("Repo", "Listener removed")
_dbCarsListReference.removeEventListener(userCarsListener)
}
}
這是我的回收站視圖配接器:
class CarsListAdapter(
private val carDeleteCallback: (id: String) -> Unit
): RecyclerView.Adapter<CarsListAdapter.CarViewHolder>() {
private val data = mutableListOf<Car>()
class CarViewHolder(private val binding: ItemCarBinding): RecyclerView.ViewHolder(binding.root) {
fun bind(car: Car) {
binding.tvCarName.text = car.name
binding.tvCarBrand.text = car.brand
binding.tvCarModel.text = car.model
binding.tvCarPlates.text = if(car.plates.isEmpty()) "----" else car.plates
}
}
fun addCar(car: Car) {
if(!data.contains(car)) {
data.add(car)
notifyItemInserted(data.size)
}
}
fun deleteCar(position: Int) {
carDeleteCallback(data[position].id)
data.remove(data[position])
notifyItemRemoved(position)
notifyItemRangeChanged(position, itemCount)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CarViewHolder {
val itemBinding = ItemCarBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return CarViewHolder(itemBinding)
}
override fun onBindViewHolder(holder: CarViewHolder, position: Int) {
holder.bind(data[position])
}
override fun getItemCount(): Int = data.size
}
所以基本上我有回收器視圖配接器,我在其中添加了專案觸摸助手,用于使用滑動洗掉專案。問題是專案以奇怪的順序呈現 - 當我導航到不同的片段然后再次進入這個片段時 - 順序不同。不知道為什么......我也相信我應該使用一些不同的方法洗掉firebase中的專案。可能我應該在配接器中呼叫回呼,在存盤庫中呼叫洗掉方法,然后在呼叫 onChildRemoved 時,從回收器視圖中洗掉專案?
希望有人知道根據 MVVM 架構這種方法是否正確,或者是否有更好的方法(例如,git repos 會很棒)。
謝謝!
uj5u.com熱心網友回復:
可能我應該在配接器中呼叫回呼,在存盤庫中呼叫洗掉方法,然后在呼叫 onChildRemoved 時,從回收器視圖中洗掉專案?
這確實是這里的正常方法:您在資料庫上執行操作,然后反應性地更新您的應用程式狀態和用戶界面。這有時也稱為CQRS:命令查詢職責分離。
這里的一個額外好處是 Firebase SDK 會立即為本地寫入操作觸發本地事件,例如onChildAdded當您添加子節點時。這意味著您無需等待資料庫回應,甚至在沒有資料庫連接時也能正常作業。在資料庫(通常是您的安全規則)拒絕寫入的(不太常見的)情況下,SDK 將觸發所謂的協調事件,例如 a onChildRemoved,以確保您的 UI 可以顯示來自資料庫的正確狀態。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/406218.html
標籤:
上一篇:檔案參考必須有偶數個段
