সবাই কেমন আছেন!
এই নিবন্ধে, আমি RecyclerView ব্যবহার করার সময় অপ্টিমাইজ করার দ্রুত উপায়গুলি দেখতে চাই।
RecyclerView হল একটি ইউজার ইন্টারফেস উপাদান যা হল একটি উপাদান যা সুবিধামত একটি তালিকা প্রদর্শন করতে ইন্টারফেসে যোগ করা যেতে পারে। এটি কোডের মধ্যে তৈরি করা হয়েছে এবং তালিকাটি প্রদর্শন, অ্যানিমেটিং এবং অপ্টিমাইজ করার জন্য ইতিমধ্যেই সরঞ্জাম রয়েছে এবং কাস্টমাইজেশন সেটিংস সমর্থন করে।
RecyclerView সঠিকভাবে কাজ করার জন্য, আপনাকে অবশ্যই নিম্নলিখিত উপাদানগুলি বাস্তবায়ন করতে হবে:
RecyclerView
, যা অবশ্যই আমাদের কার্যকলাপের লেআউটে যোগ করতে হবে;Adapter
, যা তালিকার সাথে ডেটা ধারণ করে, প্রক্রিয়া করে এবং সংযুক্ত করে;ListAdapter
, আপডেট করা অ্যাডাপ্টার এবং কন্সট্রাক্টরে DiffUtil গ্রহণ করে;ViewHolder
, যা সম্পদ অপ্টিমাইজ করতে কাজ করে এবং তালিকায় অন্তর্ভুক্ত সমস্ত উপাদানের জন্য এক ধরনের ধারক;DiffUtil
, যা তালিকা অপ্টিমাইজ করতে ব্যবহৃত হয়।
স্ক্র্যাচ থেকে কীভাবে এটি বাস্তবায়ন করা যায় তা আমি দেখব না, আপনি লিঙ্কটিতে এটি খুঁজে পেতে পারেন।
বাইন্ডিং করার সময় ভিউহোল্ডারে রিসোর্স এবং কাস্টিং অ্যাক্সেস সরান।
উদাহরণস্বরূপ, নীচের কোড নিন:
data class TrackingUiModel( val id: Long, val title: String, @ColorRes val color: Int, val eventId: Long, val state: TrackingState, val startTime: Long, val endTime: Long, val countTime: Long, val formattedTime: String, ) class TrackingViewHolder(itemView: View): ViewHolder(itemView) { private val binding : TrackingItemBinding by viewBinding() @SuppressLint("SetTextI18n") fun bind(data: TrackingUiModel) { val stateText = when (data.state) { TrackingState.START -> itemView.context.getString(R.string.in_progress) TrackingState.PAUSE -> itemView.context.getString(R.string.pause) else -> { "" } } binding.eventId.text = data.eventId.toString() binding.eventTitle.text = "${data.title} $stateText" binding.eventColor.setBackgroundColor(ContextCompat.getColor(itemView.context, data.color)) binding.countTextView.text = data.formattedTime } }
প্রতিবার bind
মেথড কল করা হলে, getString
এবং getColor
কল করা হবে, এবং toString
কেও স্ট্রিং কাস্টিংয়ের জন্য কল করা হবে। এইভাবে আমরা আরও মেমরি গ্রাস করি। এবং আপনাকে নিশ্চিত করতে হবে যে bind
পদ্ধতিটি দ্রুত কার্যকর করা হয়েছে, এবং আপনাকে নিশ্চিত করতে চেষ্টা করা উচিত যে ViewHolder
কাজটি শুধুমাত্র তালিকা আইটেমগুলি প্রদর্শন করছে। অপ্টিমাইজেশানের জন্য, TrackingUiModel
অবজেক্টে স্ট্রিং eventId
, stateText
এবং রঙ পাওয়া ভাল।
অপ্টিমাইজ করা কোড এখন এই মত দেখায়:
data class TrackingUiModel( val id: Long, val title: String, val color: Int, val eventId: String, val state: TrackingState, val stateText: String, val startTime: Long, val endTime: Long, val countTime: Long, val formattedTime: String, ) class TrackingViewHolder(itemView: View): ViewHolder(itemView) { private val binding : TrackingItemBinding by viewBinding() fun bind(data: TrackingUiModel) { binding.eventId.text = data.eventId binding.eventTitle.text = "${data.title} ${data.stateText}" binding.eventColor.setBackgroundColor(data.color) binding.countTextView.text = data.formattedTime } }
আমরা ViewHolder
ছাড়িয়ে সবকিছু নিয়েছি, আমাদের যা কিছু প্রয়োজন এবং রেডিমেড যা TrackingUiModel
এ পাওয়া যাবে।
আপনি যদি RecyclerView.Adapter
ব্যবহার করেন তাহলে আপনাকে ListAdapter
এ স্যুইচ করতে হবে এবং এর সাথে DiffUtil
ব্যবহার করতে হবে।
উদাহরণস্বরূপ, নীচের কোড নিন:
class TrackingAdapter: RecyclerView.Adapter<TrackingViewHolder>(){ private val mItems = mutableListOf<TrackingUiModel>() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackingViewHolder { return TrackingViewHolder( LayoutInflater.from(parent.context) .inflate(R.layout.tracking_item, parent, false)) } override fun getItemCount(): Int = mItems.size override fun onBindViewHolder(holder: TrackingViewHolder, position: Int) { holder.bind(mItems[position]) } fun setItems(items: List<TrackingUiModel>){ mItems.clear() mItems.addAll(items) notifyDataSetChanged() } }
তালিকার উপাদানগুলি যোগ করার সময়, setItems
পদ্ধতিতে কল করা তালিকাটি সাফ করে, তালিকার উপাদানগুলি যোগ করে এবং অবশেষে notifyDataSetChanged
কল করে।
আসুন কল্পনা করি যে আমরা তালিকা পরিবর্তন বা আপডেট করি, এবং setItems
পদ্ধতি প্রতিবার কল করা হবে; এই বেশ সম্পদ গ্রাসকারী হবে. এই কারণে, ListAdapter
এবং DiffUtil
ব্যবহার করা ভাল।
নীচে একটি পরিবর্তিত TrackingAdapter
রয়েছে যা ListAdapter
প্রয়োগ করে এবং DiffUtil
ব্যবহার করে; আমার উদাহরণে, এটি TrackingDiffCallback
ক্লাস।
একটি তালিকা যোগ করার জন্য, আমরা trackingAdapter.submitList
পদ্ধতি ব্যবহার করি এবং হুডের নিচে, অ্যাডাপ্টার আমাদের জন্য তালিকা আপডেট করার সমস্ত কাজ করবে।
class TrackingAdapter: ListAdapter<TrackingUiModel, TrackingViewHolder>(TrackingDiffCallback()){ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackingViewHolder { return TrackingViewHolder( LayoutInflater.from(parent.context) .inflate(R.layout.tracking_item, parent, false)) } override fun onBindViewHolder(holder: TrackingViewHolder, position: Int) { holder.bind(getItem(position)) } }
class TrackingDiffCallback: DiffUtil.ItemCallback<TrackingUiModel>() { override fun areItemsTheSame(oldItem: TrackingUiModel, newItem: TrackingUiModel): Boolean { return oldItem.id == newItem.id } override fun areContentsTheSame(oldItem: TrackingUiModel, newItem: TrackingUiModel): Boolean { return oldItem == newItem } }
পছন্দের তালিকার আইটেমগুলি যোগ করা, একটি চিত্র পরিবর্তন করা বা একটি তালিকা আইটেমের অন্য কিছু দৃশ্য পরিবর্তন করার মতো ঘটনা রয়েছে। এই সমস্ত ক্ষেত্রে পরিবর্তন ঘটলে, ViewHolder
এ বাইন্ড পদ্ধতি আবার বলা হয় এবং আমরা উপাদানটির হাইলাইটটি দৃশ্যত লক্ষ্য করি। এটি যাতে না ঘটে তার জন্য, পেলোড সাহায্যের জন্য আমাদের কাছে আসে।
পেলোড ব্যবহার করতে, আসুন ViewHolder
, DiffUtil
, এবং Adapter
এ একটি পরিবর্তন করি।
আমার ক্ষেত্রে, আমি নিম্নলিখিত পরিবর্তনগুলি করব৷
TrackingViewHolder-এ, আমরা পরিবর্তন করা প্রয়োজন এমন ডেটার সাথে একটি বাঁধাই পদ্ধতি যোগ করি।
fun bind(data: TrackingUiModel, newTime: String) { binding.eventId.text = data.eventId binding.eventTitle.text = "${data.title} ${data.stateText}" binding.eventColor.setBackgroundColor(data.color) binding.countTextView.text = newTime }
TrackingDiffCallback
এ, আমরা getChangePayload
পদ্ধতিকে ওভাররাইড করি এবং পরিবর্তিত ক্ষেত্রটির তুলনা করি। আমার ক্ষেত্রে, এটি formattedTime
।
override fun getChangePayload(oldItem: TrackingUiModel, newItem: TrackingUiModel): Any? { if (oldItem.formattedTime != newItem.formattedTime) return newItem.formattedTime return super.getChangePayload(oldItem, newItem) }
TrackingListAdapter,
আমরা পেলোড সহ onBindViewHolder
পদ্ধতিকে ওভাররাইড করি। আমরা পেলোডটি খালি কিনা তা পরীক্ষা করি, যদি এটি খালি না হয় তবে আমরা প্রথম উপাদানটি পাই এবং পেলোডের জন্য বাইন্ড পদ্ধতিতে কল করি।
override fun onBindViewHolder(holder: TrackingViewHolder, position: Int, payloads: MutableList<Any>) { if (payloads.isEmpty()) { super.onBindViewHolder(holder, position, payloads) } else { val newTime = payloads.firstOrNull() as? String ?: "" holder.bind(getItem(position), newTime) } }
রেফারেন্স লিঙ্ক: