Android Kotlin Fundamentals 07.5: RecyclerView-এ হেডার

এই কোডল্যাবটি অ্যান্ড্রয়েড কোটলিন ফান্ডামেন্টাল কোর্সের অংশ। আপনি যদি ক্রমানুসারে কোডল্যাবগুলির মাধ্যমে কাজ করেন তবে আপনি এই কোর্সের সর্বাধিক মূল্য পাবেন৷ সমস্ত কোর্স কোডল্যাব অ্যান্ড্রয়েড কোটলিন ফান্ডামেন্টাল কোডল্যাব ল্যান্ডিং পৃষ্ঠায় তালিকাভুক্ত করা হয়েছে।

ভূমিকা

এই কোডল্যাবে, আপনি শিখবেন কিভাবে একটি শিরোনাম যোগ করতে হয় যা একটি RecyclerView এ প্রদর্শিত তালিকার প্রস্থকে বিস্তৃত করে। আপনি আগের কোডল্যাব থেকে স্লিপ-ট্র্যাকার অ্যাপ তৈরি করেন।

আপনি ইতিমধ্যে কি জানা উচিত

  • কিভাবে একটি ক্রিয়াকলাপ, টুকরো এবং ভিউ ব্যবহার করে একটি মৌলিক ব্যবহারকারী ইন্টারফেস তৈরি করবেন।
  • টুকরোগুলির মধ্যে কীভাবে নেভিগেট করবেন এবং টুকরোগুলির মধ্যে ডেটা পাস করতে কীভাবে safeArgs ব্যবহার করবেন।
  • মডেল দেখুন, মডেল কারখানা, রূপান্তর, এবং LiveData এবং তাদের পর্যবেক্ষক দেখুন।
  • কিভাবে একটি Room ডাটাবেস তৈরি করবেন, একটি DAO তৈরি করবেন এবং সত্তাকে সংজ্ঞায়িত করবেন।
  • ডাটাবেস মিথস্ক্রিয়া এবং অন্যান্য দীর্ঘ-চলমান কাজের জন্য কোরোটিনগুলি কীভাবে ব্যবহার করবেন।
  • Adapter , ViewHolder এবং আইটেম লেআউট সহ একটি মৌলিক RecyclerView কীভাবে বাস্তবায়ন করবেন।
  • RecyclerView জন্য ডেটা বাইন্ডিং কিভাবে বাস্তবায়ন করবেন।
  • ডেটা রূপান্তর করতে কীভাবে বাঁধাই অ্যাডাপ্টার তৈরি এবং ব্যবহার করবেন।
  • কিভাবে GridLayoutManager ব্যবহার করবেন।
  • RecyclerView.

আপনি কি শিখবেন

  • একটি ভিন্ন লেআউট সহ আইটেম যোগ করতে একটি RecyclerView সহ একাধিক ViewHolder কীভাবে ব্যবহার করবেন। বিশেষত, RecyclerView এ প্রদর্শিত আইটেমগুলির উপরে একটি শিরোনাম যুক্ত করতে একটি দ্বিতীয় ViewHolder কীভাবে ব্যবহার করবেন।

আপনি কি করবেন

  • এই সিরিজের আগের কোডল্যাব থেকে TrackMySleepQuality অ্যাপ তৈরি করুন।
  • RecyclerView প্রদর্শিত ঘুমের রাতের উপরে স্ক্রিনের প্রস্থ বিস্তৃত একটি হেডার যোগ করুন।

আপনি যে স্লিপ-ট্র্যাকার অ্যাপটি দিয়ে শুরু করেন তাতে তিনটি স্ক্রীন রয়েছে, যা খন্ড দ্বারা উপস্থাপিত, নীচের চিত্রে দেখানো হয়েছে।

বাম দিকে দেখানো প্রথম স্ক্রিনে ট্র্যাকিং শুরু এবং বন্ধ করার জন্য বোতাম রয়েছে৷ স্ক্রিনটি ব্যবহারকারীর ঘুমের কিছু ডেটা দেখায়। ক্লিয়ার বোতামটি স্থায়ীভাবে সমস্ত ডেটা মুছে দেয় যা অ্যাপ ব্যবহারকারীর জন্য সংগ্রহ করেছে। দ্বিতীয় স্ক্রীন, মাঝখানে দেখানো হয়েছে, একটি ঘুমের মানের রেটিং নির্বাচন করার জন্য। তৃতীয় স্ক্রীনটি একটি বিশদ দৃশ্য যা ব্যবহারকারী গ্রিডে একটি আইটেম ট্যাপ করলে খোলে।

এই অ্যাপটি একটি UI কন্ট্রোলার, ভিউ মডেল এবং LiveData সহ একটি সরলীকৃত আর্কিটেকচার এবং ঘুমের ডেটা বজায় রাখার জন্য একটি Room ডাটাবেস ব্যবহার করে৷

এই কোডল্যাবে, আপনি প্রদর্শিত আইটেমগুলির গ্রিডে একটি শিরোনাম যোগ করুন। আপনার চূড়ান্ত প্রধান পর্দা এই মত দেখাবে:

এই কোডল্যাবটি একটি RecyclerView এ বিভিন্ন লেআউট ব্যবহার করে এমন আইটেমগুলিকে অন্তর্ভুক্ত করার সাধারণ নীতি শেখায়। একটি সাধারণ উদাহরণ হল আপনার তালিকা বা গ্রিডে হেডার থাকা। আইটেম বিষয়বস্তু বর্ণনা করার জন্য একটি তালিকার একটি একক শিরোনাম থাকতে পারে। একটি তালিকায় একাধিক শিরোনামও থাকতে পারে এবং একটি তালিকায় আলাদা আইটেম থাকতে পারে।

RecyclerView আপনার ডেটা বা প্রতিটি আইটেমের কি ধরনের বিন্যাস আছে সে সম্পর্কে কিছুই জানে না। LayoutManager স্ক্রিনে আইটেমগুলিকে সাজায়, কিন্তু অ্যাডাপ্টারটি প্রদর্শিত হওয়ার জন্য ডেটা অ্যাডাপ্ট করে এবং RecyclerView ভিউ হোল্ডারগুলিকে পাস করে। তাই আপনি অ্যাডাপ্টারে হেডার তৈরি করতে কোড যোগ করবেন।

হেডার যোগ করার দুটি উপায়

RecyclerView এ, তালিকার প্রতিটি আইটেম 0 থেকে শুরু হওয়া একটি সূচক নম্বরের সাথে মিলে যায়। উদাহরণস্বরূপ:

[প্রকৃত তথ্য] -> [অ্যাডাপ্টার ভিউ]

[০: স্লিপনাইট] -> [০: স্লিপনাইট]

[1: Sleepnight] -> [1: Sleepnight]

[2: Sleepnight] -> [2: Sleepnight]

একটি তালিকায় শিরোনাম যোগ করার একটি উপায় হল আপনার অ্যাডাপ্টারটি পরিবর্তন করে একটি ভিন্ন ViewHolder ব্যবহার করার জন্য সূচীগুলি পরীক্ষা করে যেখানে আপনার শিরোনামটি দেখানো দরকার। Adapter হেডারের ট্র্যাক রাখার জন্য দায়ী থাকবে। উদাহরণস্বরূপ, টেবিলের শীর্ষে একটি শিরোনাম দেখানোর জন্য, শূন্য-সূচীকৃত আইটেমটি রাখার সময় আপনাকে হেডারের জন্য একটি ভিন্ন ViewHolder ফেরত দিতে হবে। তারপর অন্যান্য সমস্ত আইটেম শিরোনাম অফসেট সঙ্গে ম্যাপ করা হবে, নীচে দেখানো হিসাবে.

[প্রকৃত তথ্য] -> [অ্যাডাপ্টার ভিউ]

[০: হেডার]

[0: Sleepnight] -> [1: 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 প্রতিনিধিত্ব করে। আপনার ডেটাসেট তখন ডেটা ধারক আইটেমগুলির একটি তালিকা হবে।

আপনি হয় গিটহাব থেকে স্টার্টার অ্যাপ পেতে পারেন, অথবা আগের কোডল্যাবে তৈরি করা স্লিপট্র্যাকার অ্যাপটি ব্যবহার করা চালিয়ে যেতে পারেন।

  1. GitHub থেকে RecyclerViewHeaders-Starter কোড ডাউনলোড করুন। RecyclerViewHeaders-Starter ডিরেক্টরিতে এই কোডল্যাবের জন্য প্রয়োজনীয় SleepTracker অ্যাপের স্টার্টার সংস্করণ রয়েছে। আপনি চাইলে আগের কোডল্যাব থেকে আপনার সমাপ্ত অ্যাপটি চালিয়ে যেতে পারেন।
  2. SleepNightAdapter.kt খুলুন।
  3. SleepNightListener ক্লাসের নীচে, উপরের স্তরে, DataItem নামক একটি sealed ক্লাস সংজ্ঞায়িত করুন যা ডেটার একটি আইটেমকে উপস্থাপন করে।

    একটি sealed ক্লাস একটি বন্ধ প্রকারকে সংজ্ঞায়িত করে, যার অর্থ এই ফাইলটিতে DataItem সমস্ত সাবক্লাস সংজ্ঞায়িত করা আবশ্যক৷ ফলে সাবক্লাসের সংখ্যা কম্পাইলারের কাছে জানা যায়। আপনার কোডের অন্য অংশের জন্য একটি নতুন ধরনের DataItem সংজ্ঞায়িত করা সম্ভব নয় যা আপনার অ্যাডাপ্টারকে ভেঙে দিতে পারে।
sealed class DataItem {

 }
  1. DataItem ক্লাসের মূল অংশের ভিতরে, দুটি শ্রেণী সংজ্ঞায়িত করুন যা বিভিন্ন ধরনের ডেটা আইটেম উপস্থাপন করে। প্রথমটি হল একটি SleepNightItem , যা একটি SleepNight চারপাশে একটি মোড়ক, তাই এটি একটি একক মান নেয় যার নাম sleepNight । এটিকে সিল করা ক্লাসের অংশ করতে, এটিকে DataItem প্রসারিত করতে দিন।
data class SleepNightItem(val sleepNight: SleepNight): DataItem()
  1. দ্বিতীয় শ্রেণী হল Header , একটি শিরোনাম প্রতিনিধিত্ব করার জন্য। যেহেতু একটি হেডারে কোনো প্রকৃত তথ্য নেই, তাই আপনি এটিকে object হিসেবে ঘোষণা করতে পারেন। তার মানে Header শুধুমাত্র একটি উদাহরণ থাকবে। আবার, এটি DataItem প্রসারিত করুন।
object Header: DataItem()
  1. DataItem ভিতরে, শ্রেণী স্তরে, id নামে একটি abstract Long সম্পত্তি সংজ্ঞায়িত করুন। যখন অ্যাডাপ্টার DiffUtil ব্যবহার করে একটি আইটেম পরিবর্তিত হয়েছে কিনা তা নির্ধারণ করতে, DiffItemCallback কে প্রতিটি আইটেমের আইডি জানতে হবে। আপনি একটি ত্রুটি দেখতে পাবেন, কারণ SleepNightItem এবং Header বিমূর্ত সম্পত্তি id ওভাররাইড করতে হবে।
abstract val id: Long
  1. SleepNightItem এ, nightId ফেরত দিতে id ওভাররাইড করুন।
override val id = sleepNight.nightId
  1. Header , Long.MIN_VALUE ফেরত দিতে id ওভাররাইড করুন, যা একটি খুব, খুব ছোট সংখ্যা (আক্ষরিক অর্থে, -2 থেকে 63 এর শক্তি)। সুতরাং, এটি অস্তিত্বে থাকা কোনও nightId সাথে কখনই বিরোধ করবে না।
override val id = Long.MIN_VALUE
  1. আপনার সমাপ্ত কোডটি এইরকম হওয়া উচিত এবং আপনার অ্যাপটি ত্রুটি ছাড়াই তৈরি করা উচিত।
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: হেডারের জন্য একটি ভিউহোল্ডার তৈরি করুন

  1. header.xml নামে একটি নতুন লেআউট রিসোর্স ফাইলে হেডারের জন্য লেআউট তৈরি করুন যা একটি 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" />
  1. একটি স্ট্রিং রিসোর্সে "Sleep Results" বের করুন এবং এটিকে header_text বলুন।
<string name="header_text">Sleep Results</string>
  1. 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 সমর্থন করার পরিবর্তে, এটি যেকোনো ধরনের ভিউ হোল্ডার ব্যবহার করতে সক্ষম হওয়া প্রয়োজন।

আইটেম ধরনের সংজ্ঞায়িত করুন

  1. SleepNightAdapter.kt এ, শীর্ষ স্তরে, import বিবৃতির নীচে এবং SleepNightAdapter উপরে, ভিউ প্রকারের জন্য দুটি ধ্রুবক সংজ্ঞায়িত করুন।

    RecyclerView প্রতিটি আইটেমের ভিউ টাইপকে আলাদা করতে হবে, যাতে এটি সঠিকভাবে একটি ভিউ হোল্ডারকে বরাদ্দ করতে পারে।
    private val ITEM_VIEW_TYPE_HEADER = 0
    private val ITEM_VIEW_TYPE_ITEM = 1
  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 সংজ্ঞা আপডেট করুন

  1. SleepNightAdapter এর সংজ্ঞায়, ListAdapter জন্য SleepNight থেকে DataItem এ প্রথম আর্গুমেন্ট আপডেট করুন।
  2. SleepNightAdapter এর সংজ্ঞায়, ListAdapter জন্য SleepNightAdapter.ViewHolder থেকে RecyclerView.ViewHolder এ দ্বিতীয় জেনেরিক আর্গুমেন্ট পরিবর্তন করুন। আপনি প্রয়োজনীয় আপডেটের জন্য কিছু ত্রুটি দেখতে পাবেন এবং আপনার ক্লাসের শিরোনামটি নীচে দেখানোর মতো হওয়া উচিত।
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()) {

CreateViewHolder() এর উপর আপডেট করুন

  1. একটি RecyclerView.ViewHolder ফেরত দিতে onCreateViewHolder() এর স্বাক্ষর পরিবর্তন করুন।
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
  1. প্রতিটি আইটেম টাইপের জন্য উপযুক্ত ভিউ হোল্ডার পরীক্ষা করতে এবং ফেরত দিতে 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() এ আপডেট করুন

  1. onBindViewHolder() এর প্যারামিটারের ধরনটি ViewHolder থেকে RecyclerView.ViewHolder এ পরিবর্তন করুন।
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int)
  1. যদি ধারক একজন ViewHolder হয় তবে শুধুমাত্র ভিউ হোল্ডারকে ডেটা বরাদ্দ করার জন্য একটি শর্ত যোগ করুন।
        when (holder) {
            is ViewHolder -> {...}
  1. getItem() দ্বারা ফিরে আসা অবজেক্টের ধরনটিকে 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 কলব্যাক আপডেট করুন

  1. SleepNightDiffCallbackSleepNight পরিবর্তে আপনার নতুন DataItem ক্লাস ব্যবহার করতে পদ্ধতিগুলি পরিবর্তন করুন। নীচের কোডে দেখানো হিসাবে লিন্ট সতর্কতা দমন করুন।
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
    }
}

শিরোনাম যোগ করুন এবং জমা দিন

  1. SleepNightAdapter এর ভিতরে, onCreateViewHolder() এর নীচে, একটি ফাংশন addHeaderAndSubmitList() নীচে দেখানো হিসাবে সংজ্ঞায়িত করুন। এই ফাংশনটি SleepNight এর একটি তালিকা নেয়। আপনার তালিকা জমা দেওয়ার জন্য, ListAdapter দ্বারা সরবরাহিত submitList() ব্যবহার করার পরিবর্তে, আপনি একটি শিরোনাম যোগ করতে এবং তারপর তালিকা জমা দিতে এই ফাংশনটি ব্যবহার করবেন।
fun addHeaderAndSubmitList(list: List<SleepNight>?) {}
  1. addHeaderAndSubmitList() এর ভিতরে, যদি পাস করা তালিকা null হয়, শুধুমাত্র একটি হেডার ফেরত দিন, অন্যথায়, তালিকার প্রধানের সাথে শিরোনামটি সংযুক্ত করুন এবং তারপর তালিকাটি জমা দিন।
val items = when (list) {
                null -> listOf(DataItem.Header)
                else -> listOf(DataItem.Header) + list.map { DataItem.SleepNightItem(it) }
            }
submitList(items)
  1. SleepTrackerFragment.kt খুলুন এবং কলটি submitList()addHeaderAndSubmitList() এ পরিবর্তন করুন।
  1. আপনার অ্যাপটি চালান এবং ঘুমের আইটেমগুলির তালিকার প্রথম আইটেম হিসাবে আপনার শিরোনামটি কীভাবে প্রদর্শিত হয় তা পর্যবেক্ষণ করুন।

এই অ্যাপের জন্য দুটি জিনিস ঠিক করা দরকার। একটি দৃশ্যমান, এবং একটি নয়.

  • শিরোনামটি উপরের-বাম কোণে দেখায় এবং সহজে আলাদা করা যায় না।
  • একটি শিরোনাম সহ একটি সংক্ষিপ্ত তালিকার জন্য এটি খুব বেশি গুরুত্বপূর্ণ নয়, তবে আপনার UI থ্রেডে addHeaderAndSubmitList() এ তালিকা ম্যানিপুলেশন করা উচিত নয়। আইটেম কোথায় সন্নিবেশ করা প্রয়োজন তা নির্ধারণ করতে শত শত আইটেম, একাধিক শিরোনাম এবং যুক্তি সহ একটি তালিকা কল্পনা করুন। এই কাজ একটি coroutine অন্তর্গত.

coroutines ব্যবহার করতে addHeaderAndSubmitList() পরিবর্তন করুন:

  1. SleepNightAdapter ক্লাসের অভ্যন্তরে শীর্ষ স্তরে, Dispatchers.Default সাথে একটি CoroutineScope সংজ্ঞায়িত করুন। ডিফল্ট।
private val adapterScope = CoroutineScope(Dispatchers.Default)
  1. 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)
            }
        }
    }
  1. আপনার কোড তৈরি এবং চালানো উচিত, এবং আপনি কোন পার্থক্য দেখতে পাবেন না।

বর্তমানে, হেডারটি গ্রিডের অন্যান্য আইটেমগুলির মতো একই প্রস্থ, অনুভূমিকভাবে এবং উল্লম্বভাবে একটি স্প্যান গ্রহণ করে। পুরো গ্রিডটি অনুভূমিকভাবে একটি স্প্যান প্রস্থের তিনটি আইটেম ফিট করে, তাই শিরোলেখটি অনুভূমিকভাবে তিনটি স্প্যান ব্যবহার করা উচিত।

হেডারের প্রস্থ ঠিক করতে, আপনাকে GridLayoutManager বলতে হবে কখন সমস্ত কলাম জুড়ে ডেটা স্প্যান করতে হবে। আপনি একটি GridLayoutManagerSpanSizeLookup কনফিগার করে এটি করতে পারেন। এটি একটি কনফিগারেশন অবজেক্ট যা GridLayoutManager তালিকার প্রতিটি আইটেমের জন্য কতগুলি স্প্যান ব্যবহার করতে হবে তা নির্ধারণ করতে ব্যবহার করে।

  1. SleepTrackerFragment.kt খুলুন।
  2. onCreateView() এর শেষের দিকে, আপনি যেখানে manager সংজ্ঞায়িত করেছেন সেই কোডটি খুঁজুন।
val manager = GridLayoutManager(activity, 3)
  1. manager এর নিচে , দেখান অনুযায়ী manager.spanSizeLookup কে সংজ্ঞায়িত করুন। আপনাকে একটি object তৈরি করতে হবে কারণ setSpanSizeLookup একটি ল্যাম্বডা নেয় না। Kotlin এ একটি object তৈরি করতে, টাইপ করুন object : classname , এই ক্ষেত্রে GridLayoutManager.SpanSizeLookup .
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
}
  1. কনস্ট্রাক্টরকে কল করার জন্য আপনি একটি কম্পাইলার ত্রুটি পেতে পারেন। আপনি যদি তা করেন, কনস্ট্রাক্টর কল প্রয়োগ করতে Option+Enter (Mac) অথবা Alt+Enter (Windows) দিয়ে উদ্দেশ্য মেনু খুলুন।
  1. তারপরে আপনি object একটি ত্রুটি পাবেন যে আপনাকে পদ্ধতিগুলি ওভাররাইড করতে হবে। object কার্সার রাখুন, উদ্দেশ্য মেনু খুলতে Option+Enter (Mac) বা Alt+Enter (Windows) টিপুন, তারপর getSpanSize() পদ্ধতিটি ওভাররাইড করুন।
  1. getSpanSize() এর বডিতে, প্রতিটি পজিশনের জন্য সঠিক স্প্যান সাইজ ফেরত দিন। পজিশন 0 এর স্প্যান সাইজ 3, এবং অন্যান্য পজিশনের স্প্যান সাইজ 1। আপনার সম্পূর্ণ কোডটি নিচের কোডের মত হওয়া উচিত:
    manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int) =  when (position) {
                0 -> 3
                else -> 1
            }
        }
  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"
  1. আপনার অ্যাপ চালান। এটি নীচের স্ক্রিনশটের মতো হওয়া উচিত।

অভিনন্দন! আপনার কাজ শেষ

অ্যান্ড্রয়েড স্টুডিও প্রকল্প: রিসাইক্লারভিউহেডার

  • একটি শিরোনাম সাধারণত একটি আইটেম যা একটি তালিকার প্রস্থকে বিস্তৃত করে এবং একটি শিরোনাম বা বিভাজক হিসাবে কাজ করে। আইটেম বিষয়বস্তু বর্ণনা করার জন্য একটি তালিকায় একটি একক শিরোনাম থাকতে পারে, অথবা একাধিক শিরোনাম গ্রুপ আইটেম এবং একে অপরের থেকে পৃথক আইটেম থাকতে পারে।
  • একটি RecyclerView আইটেমগুলির একটি ভিন্নধর্মী সেট মিটমাট করতে একাধিক ভিউ হোল্ডার ব্যবহার করতে পারে; উদাহরণস্বরূপ, শিরোনাম এবং তালিকা আইটেম।
  • শিরোনাম যোগ করার একটি উপায় হল আপনার অ্যাডাপ্টারটি পরিবর্তন করে একটি ভিন্ন ViewHolder ব্যবহার করার জন্য সূচীগুলি পরীক্ষা করে যেখানে আপনার হেডারটি দেখানো দরকার। Adapter হেডার ট্র্যাক রাখার জন্য দায়ী।
  • হেডার যোগ করার আরেকটি উপায় হল আপনার ডেটা গ্রিডের জন্য ব্যাকিং ডেটাসেট (তালিকা) পরিবর্তন করা, যা আপনি এই কোডল্যাবে করেছেন।

শিরোনাম যোগ করার জন্য এইগুলি প্রধান পদক্ষেপ:

  • একটি শিরোনাম বা ডেটা ধারণ করতে পারে এমন একটি DataItem তৈরি করে আপনার তালিকার ডেটা বিমূর্ত করুন।
  • অ্যাডাপ্টারে হেডারের জন্য একটি লেআউট সহ একটি ভিউ হোল্ডার তৈরি করুন।
  • যেকোন ধরনের RecyclerView.ViewHolder ব্যবহার করতে অ্যাডাপ্টার এবং এর পদ্ধতি আপডেট করুন।
  • onCreateViewHolder() এ, ডেটা আইটেমের জন্য সঠিক ধরনের ভিউ হোল্ডার ফেরত দিন।
  • DataItem ক্লাসের সাথে কাজ করতে SleepNightDiffCallback আপডেট করুন।
  • একটি addHeaderAndSubmitList() ফাংশন তৈরি করুন যা ডেটাসেটে শিরোনাম যোগ করতে coroutines ব্যবহার করে এবং তারপর submitList() কল করে।
  • GridLayoutManager.SpanSizeLookup() প্রয়োগ করুন শুধুমাত্র শিরোনাম তিনটি স্প্যান প্রশস্ত করতে।

উদাসীনতা কোর্স:

অ্যান্ড্রয়েড বিকাশকারী ডকুমেন্টেশন:

এই বিভাগে একজন প্রশিক্ষকের নেতৃত্বে একটি কোর্সের অংশ হিসাবে এই কোডল্যাবের মাধ্যমে কাজ করা শিক্ষার্থীদের জন্য সম্ভাব্য হোমওয়ার্ক অ্যাসাইনমেন্ট তালিকাভুক্ত করা হয়েছে। নিম্নলিখিতগুলি করা প্রশিক্ষকের উপর নির্ভর করে:

  • প্রয়োজনে হোমওয়ার্ক বরাদ্দ করুন।
  • শিক্ষার্থীদের সাথে যোগাযোগ করুন কিভাবে হোমওয়ার্ক অ্যাসাইনমেন্ট জমা দিতে হয়।
  • হোমওয়ার্ক অ্যাসাইনমেন্ট গ্রেড.

প্রশিক্ষকরা এই পরামর্শগুলি যতটা কম বা যতটা চান ততটা ব্যবহার করতে পারেন, এবং তাদের উপযুক্ত মনে করে অন্য কোনও হোমওয়ার্ক বরাদ্দ করতে নির্দ্বিধায় করা উচিত।

আপনি যদি নিজে থেকে এই কোডল্যাবের মাধ্যমে কাজ করে থাকেন, তাহলে আপনার জ্ঞান পরীক্ষা করার জন্য এই হোমওয়ার্ক অ্যাসাইনমেন্টগুলিকে নির্দ্বিধায় ব্যবহার করুন৷

এই প্রশ্নগুলোর উত্তর দাও

প্রশ্ন 1

নিচের কোন বিবৃতিটি ViewHolder সম্পর্কে সত্য?

▢ একটি অ্যাডাপ্টার শিরোনাম এবং বিভিন্ন ধরণের ডেটা ধরে রাখতে একাধিক ViewHolder ক্লাস ব্যবহার করতে পারে।

▢ আপনার কাছে ডেটার জন্য ঠিক একটি ভিউ হোল্ডার এবং হেডারের জন্য একটি ভিউ হোল্ডার থাকতে পারে।

▢ একটি RecyclerView একাধিক ধরণের হেডার সমর্থন করে, তবে ডেটাটি অভিন্ন হতে হবে।

▢ একটি হেডার যোগ করার সময়, আপনি সঠিক অবস্থানে শিরোনাম সন্নিবেশ করার জন্য RecyclerView সাবক্লাস করুন।

প্রশ্ন 2

আপনার কখন RecyclerView সাথে কোরোটিন ব্যবহার করা উচিত? সত্য যে সমস্ত বিবৃতি নির্বাচন করুন.

▢ কখনই না। একটি RecyclerView একটি UI উপাদান এবং কোরোটিন ব্যবহার করা উচিত নয়।

▢ দীর্ঘমেয়াদী কাজের জন্য কোরোটিন ব্যবহার করুন যা UI কে ধীর করে দিতে পারে।

▢ তালিকা ম্যানিপুলেশন করতে অনেক সময় লাগতে পারে, এবং আপনার সবসময় কোরোটিন ব্যবহার করে সেগুলি করা উচিত।

▢ মূল থ্রেড ব্লক করা এড়াতে সাসপেন্ড ফাংশন সহ করটিন ব্যবহার করুন।

প্রশ্ন 3

একাধিক ViewHolder ব্যবহার করার সময় নিচের কোনটি আপনাকে করতে হবে না?

ViewHolder , প্রয়োজন অনুযায়ী স্ফীত করার জন্য একাধিক লেআউট ফাইল প্রদান করুন।

onCreateViewHolder() এ, ডেটা আইটেমের জন্য সঠিক ধরনের ভিউ হোল্ডার ফেরত দিন।

onBindViewHolder() -এ, শুধুমাত্র ডেটা আবদ্ধ করুন যদি ভিউ হোল্ডার ডেটা আইটেমের জন্য সঠিক ধরনের ভিউ হোল্ডার হয়।

▢ যেকোন RecyclerView.ViewHolder গ্রহণ করতে অ্যাডাপ্টার শ্রেণীর স্বাক্ষরকে সাধারণীকরণ করুন।

পরবর্তী পাঠ শুরু করুন: 8.1 ইন্টারনেট থেকে ডেটা পাওয়া

এই কোর্সে অন্যান্য কোডল্যাবগুলির লিঙ্কগুলির জন্য, Android Kotlin Fundamentals codelabs ল্যান্ডিং পৃষ্ঠাটি দেখুন।