এই কোডল্যাবটি Android Kotlin Fundamentals কোর্সের অংশ। আপনি যদি কোডল্যাবগুলি ক্রমানুসারে কাজ করেন তবে আপনি এই কোর্সের সর্বাধিক মূল্য পাবেন৷ সমস্ত কোর্স কোডল্যাব অ্যান্ড্রয়েড কোটলিন ফান্ডামেন্টাল কোডল্যাব ল্যান্ডিং পৃষ্ঠায় তালিকাভুক্ত করা হয়েছে।
ভূমিকা
এই কোডল্যাবে, আপনি কীভাবে একটি শিরোনাম যুক্ত করবেন তা শিখবেন যেটি একটি RecyclerView
এ প্রদর্শিত তালিকার প্রস্থকে বিস্তৃত করে। আপনি আগের কোডল্যাব থেকে স্লিপ-ট্র্যাকার অ্যাপ তৈরি করেন।
আপনি ইতিমধ্যে কি জানা উচিত
- কিভাবে একটি কার্যকলাপ, টুকরা, এবং দৃশ্য ব্যবহার করে একটি মৌলিক ব্যবহারকারী ইন্টারফেস তৈরি করতে হয়।
- টুকরোগুলির মধ্যে কীভাবে নেভিগেট করবেন এবং টুকরোগুলির মধ্যে ডেটা পাস করতে কীভাবে
safeArgs
ব্যবহার করবেন। - মডেল দেখুন, মডেল কারখানা, রূপান্তর, এবং
LiveData
এবং তাদের পর্যবেক্ষক দেখুন। - কিভাবে একটি
Room
ডাটাবেস তৈরি করতে হয়, একটি DAO তৈরি করতে হয় এবং সত্তাকে সংজ্ঞায়িত করতে হয়। - ডাটাবেস মিথস্ক্রিয়া এবং অন্যান্য দীর্ঘ-চলমান কাজগুলির জন্য কোরোটিনগুলি কীভাবে ব্যবহার করবেন।
-
Adapter
,ViewHolder
এবং আইটেম লেআউট সহ একটি মৌলিকRecyclerView
কীভাবে বাস্তবায়ন করবেন। -
RecyclerView
জন্য ডেটা বাইন্ডিং কিভাবে বাস্তবায়ন করবেন। - ডেটা রূপান্তর করতে কীভাবে বাঁধাই অ্যাডাপ্টার তৈরি এবং ব্যবহার করবেন।
- কিভাবে
GridLayoutManager
ব্যবহার করবেন। - রিসাইক্লারভিউতে আইটেমগুলিতে ক্লিকগুলি কীভাবে ক্যাপচার এবং পরিচালনা করুন
RecyclerView.
আপনি কি শিখবেন
- একটি ভিন্ন লেআউট সহ আইটেম যোগ করতে একটি
RecyclerView
সহ একাধিকViewHolder
কীভাবে ব্যবহার করবেন। বিশেষত,RecyclerView
এ প্রদর্শিত আইটেমগুলির উপরে একটি শিরোনাম যুক্ত করতে একটি দ্বিতীয়ViewHolder
কীভাবে ব্যবহার করবেন।
আপনি কি করবেন
- এই সিরিজের আগের কোডল্যাব থেকে TrackMySleepQuality অ্যাপ তৈরি করুন।
-
RecyclerView
প্রদর্শিত ঘুমের রাতের উপরে স্ক্রিনের প্রস্থ বিস্তৃত একটি হেডার যোগ করুন।
আপনি যে স্লিপ-ট্র্যাকার অ্যাপটি দিয়ে শুরু করেছেন তাতে তিনটি স্ক্রীন রয়েছে, যা খন্ড দ্বারা উপস্থাপিত, নীচের চিত্রে দেখানো হয়েছে।
বাম দিকে দেখানো প্রথম স্ক্রীনে ট্র্যাকিং শুরু এবং বন্ধ করার জন্য বোতাম রয়েছে। স্ক্রিনটি ব্যবহারকারীর ঘুমের কিছু ডেটা দেখায়। ক্লিয়ার বোতামটি স্থায়ীভাবে সমস্ত ডেটা মুছে দেয় যা অ্যাপ ব্যবহারকারীর জন্য সংগ্রহ করেছে। দ্বিতীয় স্ক্রীন, মাঝখানে দেখানো হয়েছে, ঘুমের মানের রেটিং নির্বাচন করার জন্য। তৃতীয় স্ক্রীনটি একটি বিশদ দৃশ্য যা ব্যবহারকারী গ্রিডে একটি আইটেম ট্যাপ করলে খোলে।
এই অ্যাপটি একটি UI কন্ট্রোলার সহ একটি সরলীকৃত আর্কিটেকচার ব্যবহার করে, মডেল এবং LiveData
দেখুন, এবং ঘুমের ডেটা বজায় রাখার জন্য একটি Room
ডেটাবেস।
এই কোডল্যাবে, আপনি প্রদর্শিত আইটেমগুলির গ্রিডে একটি শিরোনাম যোগ করুন। আপনার চূড়ান্ত প্রধান পর্দা এই মত দেখাবে:
এই RecyclerView
একটি RecyclerView-এ বিভিন্ন লেআউট ব্যবহার করে এমন আইটেমগুলিকে অন্তর্ভুক্ত করার সাধারণ নীতি শেখায়। একটি সাধারণ উদাহরণ হল আপনার তালিকা বা গ্রিডে হেডার থাকা। আইটেম বিষয়বস্তু বর্ণনা করার জন্য একটি তালিকার একটি একক শিরোনাম থাকতে পারে। একটি তালিকায় একাধিক শিরোনামও থাকতে পারে এবং একটি তালিকায় আলাদা আইটেম থাকতে পারে।
RecyclerView
আপনার ডেটা বা প্রতিটি আইটেমের কি ধরনের বিন্যাস আছে সে সম্পর্কে কিছুই জানে না। LayoutManager
স্ক্রিনে আইটেমগুলিকে সাজায়, কিন্তু অ্যাডাপ্টারটি প্রদর্শিত হওয়ার জন্য ডেটা অ্যাডাপ্ট করে এবং RecyclerView
ভিউ হোল্ডারগুলিকে পাস করে। তাই আপনি অ্যাডাপ্টারে হেডার তৈরি করতে কোড যোগ করবেন।
হেডার যোগ করার দুটি উপায়
RecyclerView
তে, তালিকার প্রতিটি আইটেম 0 থেকে শুরু হওয়া একটি সূচক নম্বরের সাথে মিলে যায়। উদাহরণস্বরূপ:
[প্রকৃত তথ্য] -> [অ্যাডাপ্টার ভিউ]
[০: স্লিপনাইট] -> [০: স্লিপনাইট]
[1: Sleepnight] -> [1: Sleepnight]
[2: SleepNight] -> [2: Sleepnight]
একটি তালিকায় শিরোনাম যোগ করার একটি উপায় হল আপনার অ্যাডাপ্টারটি পরিবর্তন করে একটি ভিন্ন ViewHolder
ব্যবহার করার জন্য সূচীগুলি পরীক্ষা করে যেখানে আপনার হেডারটি দেখানো দরকার। Adapter
হেডারের ট্র্যাক রাখার জন্য দায়ী থাকবে। উদাহরণস্বরূপ, টেবিলের শীর্ষে একটি শিরোনাম দেখাতে, শূন্য-সূচীকৃত আইটেমটি রাখার সময় আপনাকে শিরোনামের জন্য একটি ভিন্ন ViewHolder
ফেরত দিতে হবে। তারপর অন্যান্য সমস্ত আইটেম শিরোনাম অফসেট সঙ্গে ম্যাপ করা হবে, নীচে দেখানো হিসাবে.
[প্রকৃত তথ্য] -> [অ্যাডাপ্টার ভিউ]
[০: হেডার]
[0: Sleepnight] -> [1: Sleepnight]
[1: Sleepnight] -> [2: Sleepnight]
[2: SleepNight] -> [3: Sleepnight.
হেডার যোগ করার আরেকটি উপায় হল আপনার ডেটা গ্রিডের জন্য ব্যাকিং ডেটাসেট পরিবর্তন করা। যেহেতু সমস্ত ডেটা প্রদর্শন করা প্রয়োজন তা একটি তালিকায় সংরক্ষণ করা হয়, আপনি একটি শিরোনাম উপস্থাপন করার জন্য আইটেমগুলি অন্তর্ভুক্ত করতে তালিকাটি সংশোধন করতে পারেন। এটি বোঝার জন্য কিছুটা সহজ, তবে আপনি কীভাবে আপনার অবজেক্টগুলি ডিজাইন করবেন সে সম্পর্কে আপনাকে ভাবতে হবে, যাতে আপনি একটি একক তালিকায় বিভিন্ন আইটেম প্রকারগুলিকে একত্রিত করতে পারেন। এইভাবে বাস্তবায়িত, অ্যাডাপ্টার এটিতে পাস করা আইটেমগুলি প্রদর্শন করবে। তাই পজিশন 0-এ থাকা আইটেমটি একটি হেডার, এবং পজিশন 1-এর আইটেমটি হল একটি SleepNight
, যা স্ক্রিনে যা আছে তা সরাসরি ম্যাপ করে।
[প্রকৃত তথ্য] -> [অ্যাডাপ্টার ভিউ]
[0: হেডার] -> [0: হেডার]
[1: Sleepnight] -> [1: Sleepnight]
[2: SleepNight] -> [2: Sleepnight]
[৩: স্লিপনাইট] -> [৩: স্লিপনাইট]
প্রতিটি পদ্ধতির সুবিধা এবং অসুবিধা রয়েছে। ডেটাসেট পরিবর্তন করলে অ্যাডাপ্টার কোডের বাকি অংশে খুব বেশি পরিবর্তন আসে না এবং আপনি ডেটার তালিকাকে ম্যানিপুলেট করে হেডার লজিক যোগ করতে পারেন। অন্যদিকে, হেডারগুলির জন্য সূচী পরীক্ষা করে একটি ভিন্ন ViewHolder
ব্যবহার করা হেডারের লেআউটে আরও স্বাধীনতা দেয়। এটি অ্যাডাপ্টারকে ব্যাকিং ডেটা পরিবর্তন না করে কীভাবে ডেটা ভিউতে অভিযোজিত হয় তা পরিচালনা করতে দেয়।
এই কোডল্যাবে, আপনি তালিকার শুরুতে একটি হেডার প্রদর্শন করতে আপনার RecyclerView
আপডেট করেন। এই ক্ষেত্রে, আপনার অ্যাপটি ডেটা আইটেমগুলির চেয়ে হেডারের জন্য একটি ভিন্ন ViewHolder
ব্যবহার করবে। কোন ViewHolder
ব্যবহার করবেন তা নির্ধারণ করতে অ্যাপটি তালিকার সূচী পরীক্ষা করবে।
ধাপ 1: একটি DataItem ক্লাস তৈরি করুন
আইটেমটির ধরন বিমূর্ত করতে এবং অ্যাডাপ্টারটিকে শুধুমাত্র "আইটেম" নিয়ে কাজ করতে দিতে, আপনি একটি ডেটা হোল্ডার শ্রেণী তৈরি করতে পারেন যা হয় একটি SleepNight
বা একটি Header
উপস্থাপন করে। আপনার ডেটাসেট তখন ডেটা ধারক আইটেমগুলির একটি তালিকা হবে।
আপনি হয় গিটহাব থেকে স্টার্টার অ্যাপটি পেতে পারেন, অথবা আগের কোডল্যাবে আপনার তৈরি করা স্লিপট্র্যাকার অ্যাপটি ব্যবহার করা চালিয়ে যেতে পারেন।
- GitHub থেকে RecyclerViewHeaders-Starter কোড ডাউনলোড করুন। RecyclerViewHeaders-Starter ডিরেক্টরিতে এই কোডল্যাবের জন্য প্রয়োজনীয় SleepTracker অ্যাপের স্টার্টার সংস্করণ রয়েছে। আপনি চাইলে আগের কোডল্যাব থেকে আপনার সমাপ্ত অ্যাপটি চালিয়ে যেতে পারেন।
- SleepNightAdapter.kt খুলুন।
-
SleepNightListener
ক্লাসের নীচে, উপরের স্তরে,DataItem
নামক একটিsealed
করা ক্লাস সংজ্ঞায়িত করুন যা ডেটার একটি আইটেমকে উপস্থাপন করে।
একটিsealed
করা শ্রেণী একটি বন্ধ প্রকারকে সংজ্ঞায়িত করে, যার অর্থ এই ফাইলটিতেDataItem
এর সমস্ত সাবক্লাস সংজ্ঞায়িত করা আবশ্যক৷ ফলে সাবক্লাসের সংখ্যা কম্পাইলারের কাছে জানা যায়। আপনার কোডের অন্য অংশের জন্য একটি নতুন ধরনেরDataItem
সংজ্ঞায়িত করা সম্ভব নয় যা আপনার অ্যাডাপ্টারকে ভেঙে দিতে পারে।
sealed class DataItem {
}
-
DataItem
ক্লাসের মূল অংশের ভিতরে, দুটি শ্রেণী সংজ্ঞায়িত করুন যা বিভিন্ন ধরনের ডেটা আইটেম উপস্থাপন করে। প্রথমটি হল একটিSleepNightItem
, যা একটিSleepNight
এর চারপাশে একটি মোড়ক, তাই এটি একটি একক মান নেয় যার নামsleepNight
। এটিকে সিল করা ক্লাসের অংশ করতে, এটিকেDataItem
।
data class SleepNightItem(val sleepNight: SleepNight): DataItem()
- দ্বিতীয় শ্রেণী হল
Header
, একটি শিরোনাম প্রতিনিধিত্ব করার জন্য। যেহেতু একটি হেডারে কোনো প্রকৃত তথ্য নেই, তাই আপনি এটিকেobject
হিসেবে ঘোষণা করতে পারেন। তার মানেHeader
শুধুমাত্র একটি উদাহরণ থাকবে। আবার, এটিDataItem
প্রসারিত করুন।
object Header: DataItem()
-
DataItem
এর ভিতরে, শ্রেণী স্তরে,id
নামে একটিabstract
Long
সম্পত্তি সংজ্ঞায়িত করুন। যখন অ্যাডাপ্টারDiffUtil
ব্যবহার করে একটি আইটেম পরিবর্তিত হয়েছে কিনা তা নির্ধারণ করতে,DiffItemCallback
কে প্রতিটি আইটেমের আইডি জানতে হবে। আপনি একটি ত্রুটি দেখতে পাবেন, কারণSleepNightItem
এবংHeader
এর বিমূর্ত সম্পত্তিid
ওভাররাইড করতে হবে।
abstract val id: Long
-
SleepNightItem
এ,nightId
ফেরত দিতেid
ওভাররাইড করুন।
override val id = sleepNight.nightId
-
Header
,Long.MIN_VALUE
ফেরত দিতেid
ওভাররাইড করুন, যা একটি খুব, খুব ছোট সংখ্যা (আক্ষরিক অর্থে, -2 থেকে 63 এর শক্তি)। সুতরাং, এটি অস্তিত্বে থাকা কোনওnightId
সাথে কখনই বিরোধ করবে না।
override val id = Long.MIN_VALUE
- আপনার সমাপ্ত কোডটি এইরকম হওয়া উচিত এবং আপনার অ্যাপটি ত্রুটি ছাড়াই তৈরি করা উচিত।
sealed class DataItem {
abstract val id: Long
data class SleepNightItem(val sleepNight: SleepNight): DataItem() {
override val id = sleepNight.nightId
}
object Header: DataItem() {
override val id = Long.MIN_VALUE
}
}
ধাপ 2: হেডারের জন্য একটি ভিউহোল্ডার তৈরি করুন
-
TextView
নামে একটি নতুন লেআউট রিসোর্স ফাইলে হেডারের জন্য লেআউট তৈরি করুন যা একটি TextView প্রদর্শন করে। এই সম্পর্কে উত্তেজনাপূর্ণ কিছুই নেই, তাই এখানে কোড আছে.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Sleep Results"
android:padding="8dp" />
- একটি স্ট্রিং রিসোর্সে
"Sleep Results"
বের করুন এবং এটিকেheader_text
।
<string name="header_text">Sleep Results</string>
- SleepNightAdapter.kt- এ,
SleepNightAdapter
এর ভিতরে,ViewHolder
ক্লাসের উপরে, একটি নতুনTextViewHolder
ক্লাস তৈরি করুন। এই ক্লাসটি textview.xml লেআউটকে স্ফীত করে এবং একটিTextViewHolder
উদাহরণ প্রদান করে। যেহেতু আপনি আগে এটি করেছেন, এখানে কোডটি রয়েছে এবং আপনাকেView
এবংR
আমদানি করতে হবে:
class TextViewHolder(view: View): RecyclerView.ViewHolder(view) {
companion object {
fun from(parent: ViewGroup): TextViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val view = layoutInflater.inflate(R.layout.header, parent, false)
return TextViewHolder(view)
}
}
}
ধাপ 3: SleepNightAdapter আপডেট করুন
পরবর্তীতে আপনাকে SleepNightAdapter
এর ঘোষণা আপডেট করতে হবে। শুধুমাত্র এক ধরনের ViewHolder
সমর্থন করার পরিবর্তে, এটি যেকোনো ধরনের ভিউ হোল্ডার ব্যবহার করতে সক্ষম হওয়া প্রয়োজন।
আইটেম ধরনের সংজ্ঞায়িত করুন
-
SleepNightAdapter.kt
এ, শীর্ষ স্তরে,import
বিবৃতির নীচে এবংSleepNightAdapter
এর উপরে, ভিউ প্রকারের জন্য দুটি ধ্রুবক সংজ্ঞায়িত করুন।
RecyclerView
কে প্রতিটি আইটেমের ভিউ টাইপকে আলাদা করতে হবে, যাতে এটি সঠিকভাবে একটি ভিউ হোল্ডার বরাদ্দ করতে পারে।
private val ITEM_VIEW_TYPE_HEADER = 0
private val ITEM_VIEW_TYPE_ITEM = 1
-
SleepNightAdapter
এর ভিতরে, একটি ফাংশন তৈরি করুনgetItemViewType()
ওভাররাইড করতে যাতে বর্তমান আইটেমের ধরনের উপর নির্ভর করে সঠিক শিরোনাম বা আইটেম ধ্রুবক ফিরে আসে।
override fun getItemViewType(position: Int): Int {
return when (getItem(position)) {
is DataItem.Header -> ITEM_VIEW_TYPE_HEADER
is DataItem.SleepNightItem -> ITEM_VIEW_TYPE_ITEM
}
}
SleepNightAdapter সংজ্ঞা আপডেট করুন
- SleepNightAdapter-এর সংজ্ঞায়,
SleepNightAdapter
এর জন্যListAdapter
থেকেSleepNight
এ প্রথম আর্গুমেন্ট আপডেটDataItem
। -
RecyclerView.ViewHolder
এর সংজ্ঞায়,SleepNightAdapter
এর জন্যListAdapter
থেকেSleepNightAdapter.ViewHolder
এ দ্বিতীয় জেনেরিক আর্গুমেন্ট পরিবর্তন করুন। আপনি প্রয়োজনীয় আপডেটের জন্য কিছু ত্রুটি দেখতে পাবেন, এবং আপনার ক্লাস শিরোনাম নীচে দেখানো মত দেখতে হবে।
class SleepNightAdapter(val clickListener: SleepNightListener):
ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {
CreateViewHolder() এর উপর আপডেট করুন
- একটি
RecyclerView.ViewHolder
ফেরত দিতেonCreateViewHolder()
এর স্বাক্ষর পরিবর্তন করুন।
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
- প্রতিটি আইটেমের প্রকারের জন্য উপযুক্ত ভিউ হোল্ডার পরীক্ষা করতে এবং ফেরত দেওয়ার জন্য
onCreateViewHolder()
পদ্ধতির বাস্তবায়ন প্রসারিত করুন। আপনার আপডেট করা পদ্ধতিটি নীচের কোডের মতো হওয়া উচিত।
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ITEM_VIEW_TYPE_HEADER -> TextViewHolder.from(parent)
ITEM_VIEW_TYPE_ITEM -> ViewHolder.from(parent)
else -> throw ClassCastException("Unknown viewType ${viewType}")
}
}
BindViewHolder() এর উপর আপডেট করুন
-
onBindViewHolder()
-এর প্যারামিটারের ধরনViewHolder
থেকেRecyclerView.ViewHolder
এ পরিবর্তন করুন।
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
- ধারক যদি ভিউ হোল্ডার হয় তবে শুধুমাত্র ভিউ
ViewHolder
ডেটা বরাদ্দ করার জন্য একটি শর্ত যোগ করুন।
when (holder) {
is ViewHolder -> {...}
-
getItem()
দ্বারা ফিরে আসা অবজেক্টেরDataItem.SleepNightItem
DataItem.SleepNightItem-এ কাস্ট করুন। আপনার সমাপ্তonBindViewHolder()
ফাংশনটি এইরকম হওয়া উচিত।
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolder -> {
val nightItem = getItem(position) as DataItem.SleepNightItem
holder.bind(nightItem.sleepNight, clickListener)
}
}
}
diffUtil কলব্যাক আপডেট করুন
- SleepNightDiffCallback-এর পদ্ধতিগুলিকে
SleepNightDiffCallback
এর পরিবর্তে আপনার নতুনDataItem
ক্লাস ব্যবহার করতেSleepNight
করুন। নীচের কোডে দেখানো হিসাবে লিন্ট সতর্কতা দমন করুন।
class SleepNightDiffCallback : DiffUtil.ItemCallback<DataItem>() {
override fun areItemsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
return oldItem.id == newItem.id
}
@SuppressLint("DiffUtilEquals")
override fun areContentsTheSame(oldItem: DataItem, newItem: DataItem): Boolean {
return oldItem == newItem
}
}
শিরোনাম যোগ করুন এবং জমা দিন
-
SleepNightAdapter
এর ভিতরে, onCreateViewHolderonCreateViewHolder()
এর নীচে, নীচে দেখানো হিসাবে একটি ফাংশনaddHeaderAndSubmitList()
সংজ্ঞায়িত করুন। এই ফাংশনটিSleepNight
এর একটি তালিকা নেয়। আপনার তালিকা জমা দেওয়ার জন্য,ListAdapter
দ্বারা সরবরাহিতsubmitList()
ব্যবহার করার পরিবর্তে, আপনি একটি শিরোনাম যোগ করতে এবং তারপর তালিকা জমা দিতে এই ফাংশনটি ব্যবহার করবেন।
fun addHeaderAndSubmitList(list: List<SleepNight>?) {}
-
addHeaderAndSubmitList()
এর ভিতরে, যদি তালিকায় পাস করাnull
হয়, শুধুমাত্র একটি হেডার ফেরত দিন, অন্যথায়, তালিকার প্রধানের সাথে শিরোনামটি সংযুক্ত করুন এবং তারপর তালিকাটি জমা দিন।
val items = when (list) {
null -> listOf(DataItem.Header)
else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
}
submitList(items)
- SleepTrackerFragment.kt খুলুন এবং কলটি
submitList()
এaddHeaderAndSubmitList()
() এ পরিবর্তন করুন।
- আপনার অ্যাপটি চালান এবং ঘুমের আইটেমগুলির তালিকার প্রথম আইটেম হিসাবে আপনার শিরোনামটি কীভাবে প্রদর্শিত হয় তা পর্যবেক্ষণ করুন।
এই অ্যাপের জন্য দুটি জিনিস ঠিক করা দরকার। একটি দৃশ্যমান, এবং একটি নয়.
- শিরোনামটি উপরের-বাম কোণে দেখায় এবং সহজে আলাদা করা যায় না।
- একটি শিরোনাম সহ একটি সংক্ষিপ্ত তালিকার জন্য এটি খুব বেশি গুরুত্বপূর্ণ নয়, তবে আপনার UI থ্রেডে
addHeaderAndSubmitList()
এ তালিকা ম্যানিপুলেশন করা উচিত নয়। আইটেম কোথায় সন্নিবেশ করা প্রয়োজন তা নির্ধারণ করতে শত শত আইটেম, একাধিক শিরোনাম এবং যুক্তি সহ একটি তালিকা কল্পনা করুন। এই কাজ একটি coroutine অন্তর্গত.
coroutines ব্যবহার করতে addHeaderAndSubmitList()
পরিবর্তন করুন:
-
SleepNightAdapter
ক্লাসের অভ্যন্তরে শীর্ষ স্তরে,Dispatchers.Default
এর সাথে একটিCoroutineScope
সংজ্ঞায়িত করুন। ডিফল্ট।
private val adapterScope = CoroutineScope(Dispatchers.Default)
-
addHeaderAndSubmitList()
এ, তালিকাটি ম্যানিপুলেট করতে অ্যাডাপ্টারস্কোপে একটিadapterScope
চালু করুন। তারপরে তালিকা জমা দিতেDispatchers.Main
প্রসঙ্গে স্যুইচ করুন, নীচের কোডে দেখানো হয়েছে।
fun addHeaderAndSubmitList(list: List<SleepNight>?) {
adapterScope.launch {
val items = when (list) {
null -> listOf(DataItem.Header)
else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
}
withContext(Dispatchers.Main) {
submitList(items)
}
}
}
- আপনার কোড তৈরি এবং চালানো উচিত, এবং আপনি কোন পার্থক্য দেখতে পাবেন না।
বর্তমানে, হেডারটি গ্রিডের অন্যান্য আইটেমগুলির মতো একই প্রস্থ, অনুভূমিকভাবে এবং উল্লম্বভাবে একটি স্প্যান গ্রহণ করে। পুরো গ্রিডটি অনুভূমিকভাবে একটি স্প্যান প্রস্থের তিনটি আইটেম ফিট করে, তাই শিরোলেখটি অনুভূমিকভাবে তিনটি স্প্যান ব্যবহার করা উচিত।
হেডারের প্রস্থ ঠিক করতে, আপনাকে GridLayoutManager
বলতে হবে কখন সমস্ত কলাম জুড়ে ডেটা স্প্যান করতে হবে। আপনি একটি GridLayoutManager
এ SpanSizeLookup
কনফিগার করে এটি করতে পারেন। এটি একটি কনফিগারেশন অবজেক্ট যা GridLayoutManager
তালিকার প্রতিটি আইটেমের জন্য কতগুলি স্প্যান ব্যবহার করতে হবে তা নির্ধারণ করতে ব্যবহার করে।
- SleepTrackerFragment.kt খুলুন।
-
onCreateView()
এর শেষের দিকে আপনিmanager
যেখানে সংজ্ঞায়িত করেছেন সেই কোডটি খুঁজুন।
val manager = GridLayoutManager(activity, 3)
-
manager
-এর নীচে, দেখানো হিসাবেmanager.spanSizeLookup
কে সংজ্ঞায়িত করুন। আপনাকে একটিobject
তৈরি করতে হবে কারণsetSpanSizeLookup
একটি ল্যাম্বডা নেয় না। কোটলিনে একটিobject
তৈরি করতে, টাইপ করুনobject : classname
, এই ক্ষেত্রেGridLayoutManager.SpanSizeLookup
.
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
- কনস্ট্রাক্টরকে কল করার জন্য আপনি একটি কম্পাইলার ত্রুটি পেতে পারেন। আপনি যদি তা করেন, কনস্ট্রাক্টর কল প্রয়োগ করতে
Option+Enter
(Mac) অথবাAlt+Enter
(Windows) দিয়ে উদ্দেশ্য মেনু খুলুন।
- তারপরে আপনি
object
একটি ত্রুটি পাবেন যে আপনাকে পদ্ধতিগুলি ওভাররাইড করতে হবে।object
কার্সার রাখুন, উদ্দেশ্য মেনু খুলতেOption+Enter
(Mac) বাAlt+Enter
(Windows) টিপুন, তারপরgetSpanSize()
পদ্ধতিটি ওভাররাইড করুন।
-
getSpanSize()
এর বডিতে, প্রতিটি পজিশনের জন্য সঠিক স্প্যান সাইজ ফেরত দিন। পজিশন 0 এর স্প্যান সাইজ 3, এবং অন্যান্য পজিশনের স্প্যান সাইজ 1। আপনার সম্পূর্ণ কোডটি নিচের কোডের মত হওয়া উচিত:
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int) = when (position) {
0 -> 3
else -> 1
}
}
- আপনার হেডারটি কেমন দেখাচ্ছে তা উন্নত করতে, header.xml খুলুন এবং লেআউট ফাইল header.xml- এ এই কোডটি যোগ করুন।
android:textColor="@color/white_text_color"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@color/colorAccent"
- আপনার অ্যাপ চালান। এটি নীচের স্ক্রিনশটের মতো হওয়া উচিত।
অভিনন্দন! তুমি পেরেছ.
অ্যান্ড্রয়েড স্টুডিও প্রকল্প: রিসাইক্লারভিউহেডার
- একটি শিরোনাম সাধারণত একটি আইটেম যা একটি তালিকার প্রস্থকে বিস্তৃত করে এবং একটি শিরোনাম বা বিভাজক হিসাবে কাজ করে। আইটেম বিষয়বস্তু বর্ণনা করার জন্য একটি তালিকায় একটি একক শিরোনাম থাকতে পারে, অথবা একাধিক শিরোনাম গ্রুপ আইটেম এবং একে অপরের থেকে পৃথক আইটেম থাকতে পারে।
- একটি
RecyclerView
আইটেমগুলির একটি ভিন্নধর্মী সেট মিটমাট করার জন্য একাধিক ভিউ হোল্ডার ব্যবহার করতে পারে; উদাহরণস্বরূপ, শিরোনাম এবং তালিকা আইটেম। - শিরোনাম যোগ করার একটি উপায় হল আপনার অ্যাডাপ্টার পরিবর্তন করে একটি ভিন্ন
ViewHolder
ব্যবহার করার জন্য সূচী পরীক্ষা করে যেখানে আপনার শিরোনাম দেখানো দরকার।Adapter
হেডারের ট্র্যাক রাখার জন্য দায়ী। - হেডার যোগ করার আরেকটি উপায় হল আপনার ডেটা গ্রিডের জন্য ব্যাকিং ডেটাসেট (তালিকা) পরিবর্তন করা, যা আপনি এই কোডল্যাবে করেছিলেন।
শিরোনাম যোগ করার জন্য এইগুলি প্রধান পদক্ষেপ:
- একটি শিরোনাম বা ডেটা ধারণ করতে পারে এমন একটি ডেটা
DataItem
তৈরি করে আপনার তালিকার ডেটা বিমূর্ত করুন। - অ্যাডাপ্টারে হেডারের জন্য একটি লেআউট সহ একটি ভিউ হোল্ডার তৈরি করুন।
- যেকোনো ধরনের
RecyclerView.ViewHolder
ব্যবহার করতে অ্যাডাপ্টার এবং এর পদ্ধতি আপডেট করুন। -
onCreateViewHolder()
এ, ডেটা আইটেমের জন্য সঠিক ধরনের ভিউ হোল্ডার ফেরত দিন। -
DataItem
ক্লাসের সাথে কাজ করতেSleepNightDiffCallback
আপডেট করুন। - একটি
addHeaderAndSubmitList()
ফাংশন তৈরি করুন যা ডেটাসেটে হেডার যোগ করতে কোরোটিন ব্যবহার করে এবং তারপরsubmitList()
কল করে। -
GridLayoutManager.SpanSizeLookup()
প্রয়োগ করুন শুধুমাত্র হেডারকে তিন স্প্যান চওড়া করতে।
উদাসীনতা কোর্স:
অ্যান্ড্রয়েড বিকাশকারী ডকুমেন্টেশন:
এই বিভাগে একজন প্রশিক্ষকের নেতৃত্বে একটি কোর্সের অংশ হিসাবে এই কোডল্যাবের মাধ্যমে কাজ করা শিক্ষার্থীদের জন্য সম্ভাব্য হোমওয়ার্ক অ্যাসাইনমেন্ট তালিকাভুক্ত করা হয়েছে। নিম্নলিখিতগুলি করা প্রশিক্ষকের উপর নির্ভর করে:
- প্রয়োজনে হোমওয়ার্ক বরাদ্দ করুন।
- শিক্ষার্থীদের সাথে যোগাযোগ করুন কিভাবে হোমওয়ার্ক অ্যাসাইনমেন্ট জমা দিতে হয়।
- হোমওয়ার্ক অ্যাসাইনমেন্ট গ্রেড.
প্রশিক্ষকরা এই পরামর্শগুলিকে তারা যতটা কম বা যতটা চান ব্যবহার করতে পারেন, এবং তাদের উপযুক্ত মনে করে অন্য কোনও হোমওয়ার্ক বরাদ্দ করতে নির্দ্বিধায় করা উচিত।
আপনি যদি নিজে থেকে এই কোডল্যাবের মাধ্যমে কাজ করে থাকেন, তাহলে আপনার জ্ঞান পরীক্ষা করার জন্য এই হোমওয়ার্ক অ্যাসাইনমেন্টগুলি ব্যবহার করুন।
এই প্রশ্নগুলোর উত্তর দাও
প্রশ্ন 1
নিচের কোন বিবৃতিটি ViewHolder
সম্পর্কে সত্য?
▢ একটি অ্যাডাপ্টার শিরোনাম এবং বিভিন্ন ধরনের ডেটা রাখার জন্য একাধিক ViewHolder
ক্লাস ব্যবহার করতে পারে।
▢ আপনার কাছে ডেটার জন্য ঠিক একটি ভিউ হোল্ডার এবং হেডারের জন্য একটি ভিউ হোল্ডার থাকতে পারে।
RecyclerView
একটি রিসাইক্লারভিউ একাধিক ধরনের হেডার সমর্থন করে, কিন্তু ডেটা একই রকম হতে হবে।
▢ একটি হেডার যোগ করার সময়, আপনি সঠিক অবস্থানে হেডার সন্নিবেশ করতে RecyclerView
সাবক্লাস করুন।
প্রশ্ন 2
আপনার কখন রিসাইক্লারভিউ এর সাথে RecyclerView
ব্যবহার করা উচিত? সত্য যে সমস্ত বিবৃতি নির্বাচন করুন.
▢ কখনই না। একটি রিসাইক্লারভিউ একটি UI উপাদান এবং RecyclerView
ব্যবহার করা উচিত নয়৷
▢ দীর্ঘমেয়াদী কাজের জন্য কোরোটিন ব্যবহার করুন যা UI কে ধীর করে দিতে পারে।
▢ তালিকা ম্যানিপুলেশন করতে অনেক সময় লাগতে পারে, এবং আপনার উচিত সবসময় কোরোটিন ব্যবহার করে সেগুলি করা।
▢ মূল থ্রেড ব্লক করা এড়াতে সাসপেন্ড ফাংশন সহ করটিন ব্যবহার করুন।
প্রশ্ন 3
একাধিক ViewHolder
ব্যবহার করার সময় নিচের কোনটি আপনাকে করতে হবে না?
▢ ViewHolder
, প্রয়োজন অনুযায়ী স্ফীত করার জন্য একাধিক লেআউট ফাইল প্রদান করুন।
▢ onCreateViewHolder onCreateViewHolder()
এ, ডেটা আইটেমের জন্য সঠিক ধরনের ভিউ হোল্ডার ফেরত দিন।
▢ onBindViewHolder()
-এ, শুধুমাত্র ডেটা আবদ্ধ করুন যদি ভিউ হোল্ডার ডেটা আইটেমের জন্য সঠিক ধরনের ভিউ হোল্ডার হয়।
RecyclerView.ViewHolder
যেকোন RecyclerView.ViewHolder গ্রহণ করতে অ্যাডাপ্টার শ্রেণীর স্বাক্ষরকে সাধারণীকরণ করুন।
পরবর্তী পাঠ শুরু করুন:
এই কোর্সে অন্যান্য কোডল্যাবগুলির লিঙ্কগুলির জন্য, Android Kotlin Fundamentals codelabs ল্যান্ডিং পৃষ্ঠাটি দেখুন।