मैं इस तरह डेटाबेस से 30 आइटम लाने के लिए LiveData का उपयोग कर रहा हूं:
@Query("SELECT * FROM table ORDER BY id DESC LIMIT 30")
fun getLast30(): LiveData<List<Person>>
प्रत्येक पुनरावर्तक दृश्य आइटम में एक समान बटन होता है और मेरे पास एडेप्टर में एक इंटरफ़ेस होता है:
interface OnItemClickedAdapter {
fun onFavButtonClicked(position: Int)
}
अंत जब जैसे बटन पर क्लिक किया गया तो मैं डेटाबेस में एक आइटम अपडेट कर रहा हूं। जैसा कि मैं लाइवडाटा का उपयोग कर रहा हूं, यह अद्यतन 30 आइटम ला रहा है। मैं उस डेटा को निरीक्षण विधि का उपयोग करके सेट कर रहा हूं:
viewModel.last30.observe(viewLifecycleOwner, {
adapter.submitList(it)
}
समस्या:
- जब एक लाइक बटन पर क्लिक किया जाता है, तो रिसाइकलर व्यू अपनी सभी सामग्री को रीफ्रेश कर रहा होता है और यह पहले आइटम पर स्क्रॉल करता है।
संपादित: सबमिटलिस्ट (सूची: सूची) विधि:
fun submitList(persons: List<Person>) {
val diffResult: DiffUtil.DiffResult = DiffUtil.calculateDiff(
ApodGalleryAdapterDiffCallback(
this.persons,
persons
)
)
this.persons = person
diffResult.dispatchUpdatesTo(this)
}
डिफ्यूटिल क्लास:
class PersonAdapterDiffCallback(var oldList: List<Person>, var newList: List<Person>) :
DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].url == newList[newItemPosition].url
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition]
}
}
अनुकूलक वर्ग:
class ApodGalleryAdapter() :
RecyclerView.Adapter<ApodGalleryAdapter.ApodGalleryViewHolder>() {
var onItemClickedGalleryAdapter: OnItemClickedGalleryAdapter? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ApodGalleryViewHolder {
return ApodGalleryViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_apod_gallery, parent, false),
onItemClickedGalleryAdapter
)
}
private var apods: List<Apod> = ArrayList()
override fun getItemCount(): Int {
return apods.size
}
override fun onBindViewHolder(holder: ApodGalleryViewHolder, position: Int) {
holder.bindData(apods[position], position)
}
fun submitList(apods: List<Apod>) {
val diffResult: DiffUtil.DiffResult = DiffUtil.calculateDiff(
ApodGalleryAdapterDiffCallback(
this.apods,
apods
)
)
this.apods = apods
diffResult.dispatchUpdatesTo(this)
}
class ApodGalleryViewHolder(
itemView: View,
var onItemClickedGalleryAdapter: OnItemClickedGalleryAdapter?
) :
RecyclerView.ViewHolder(itemView) {
private val apodImage: ImageView = itemView.image_item_apod
private val apodTitle: TextView = itemView.title_item_apod
private val apodDescription: TextView = itemView.description_item_apod
private val apodCopyright: TextView = itemView.copyright_item_apod
fun bindData(apod: Apod, position: Int) {
when {
apod.url.endsWith(".jpg") -> {
Glide.with(apodImage.context)
.load(apod.url)
.placeholder(R.drawable.transparent)
.into(apodImage)
}
apod.url.contains("youtube") -> {
Glide.with(apodImage.context)
.load(getThumbnailUrl(apod.url))
.placeholder(R.drawable.transparent)
.into(apodImage)
}
else -> {
apodImage.setImageResource(R.drawable.transparent)
}
}
apodTitle.text = apod.title
apodDescription.text = apod.explanation
apodCopyright.text = apod.copyright
if (apod.isLiked) {
itemView.fav_button_item_apod_gallery.setImageResource(R.drawable.ic_round_favorite_24)
} else {
itemView.fav_button_item_apod_gallery.setImageResource(R.drawable.ic_round_favorite_border_24)
}
itemView.setOnClickListener {
onItemClickedGalleryAdapter?.onClick(apod.date)
}
itemView.fav_button_item_apod_gallery.setOnClickListener {
onItemClickedGalleryAdapter?.onFavButtonClicked(position)
}
}
}
}
interface OnItemClickedGalleryAdapter {
fun onClick(date: String)
fun onFavButtonClicked(position: Int)
}
class ApodGalleryAdapterDiffCallback(var oldList: List<Apod>, var newList: List<Apod>) :
DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].url == newList[newItemPosition].url
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition]
}
}
मैंने अपने डेटा वर्ग की equals()
विधि को अधिलेखित कर दिया है:
override fun equals(other: Any?): Boolean {
if (javaClass != other?.javaClass)
return false
other as Apod
if (id != other.id)
return false
if (copyright != other.copyright)
return false
if (date != other.date)
return false
if (explanation != other.explanation)
return false
if (hdUrl != other.hdUrl)
return false
if (media_type != other.media_type)
return false
if (service_version != other.service_version)
return false
if (url != other.url)
return false
if (isLiked != other.isLiked)
return false
return true
}
2 जवाब
मैं liveData, DiffUtill और adapter.notifyItemChanged(position)
के माध्यम से समाधान खोज रहा था।
असली समस्या मेरे पर्यवेक्षक ब्लॉक में है:
viewModel.apod30Days.observe(viewLifecycleOwner, {
adapter.submitList(it)
adapter.onItemClickedGalleryAdapter = object : OnItemClickedGalleryAdapter {
override fun onClick(date: String) {
val intent =
Intent(requireActivity().applicationContext, DetailsActivity::class.java)
intent.putExtra(DetailsActivity.APOD_DATE_KEY, date)
startActivity(intent)
}
override fun onFavButtonClicked(position: Int) {
val apod = it[position]
apod.isLiked = !apod.isLiked
viewModel.updateApod(apod)
adapter.notifyItemChanged(position)
}
}
if (it.size < 30)
viewModel.setLast30Apods()
binding.apodViewPager.adapter = adapter
})
इस ब्लॉक की अंतिम पंक्ति में, मैं एडॉप्टर को बार-बार सेट कर रहा हूं जब लाइवडाटा बदलता है। DiffUtill पूरी तरह से काम कर रहा था।
DiffUtil
कार्यान्वयन में, areContentsTheSame
हमेशा false
लौटाता है।
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition] // always returns false
}
आपको प्रत्येक चर को इस तरह जांचना होगा:
//for example
data class Person(
val name:String,
val age:Int
)
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldList[oldItemPosition]
val newItem = newList[newItemPosition]
return oldItem.name.equals(newItem.name) &&
oldItem.age == newItem.age
}
संबंधित सवाल
नए सवाल
android
एंड्रॉइड Google का मोबाइल ऑपरेटिंग सिस्टम है, जिसका उपयोग प्रोग्रामिंग या डिजिटल डिवाइस (स्मार्टफोन, टैबलेट, ऑटोमोबाइल्स, टीवी, वियर, ग्लास, IoT) को विकसित करने के लिए किया जाता है। एंड्रॉइड से संबंधित विषयों के लिए, एंड्रॉइड-विशिष्ट टैग जैसे कि एंड्रॉइड-इरादे, एंड्रॉइड-गतिविधि, एंड्रॉइड-एडॉप्टर आदि का उपयोग करें। विकास या प्रोग्रामिंग के अलावा अन्य प्रश्नों के लिए, लेकिन एंड्रॉइड फ्रेमवर्क से संबंधित हैं, इस लिंक का उपयोग करें: https: // android.stackexchange.com।