Android Kotlin Fundamentals 05.1: ViewModel এবং ViewModelFactory

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

শিরোনাম পর্দা

খেলা পর্দা

স্কোর স্ক্রীন

ভূমিকা

এই কোডল্যাবে, আপনি অ্যান্ড্রয়েড আর্কিটেকচার উপাদানগুলির একটি সম্পর্কে শিখবেন, ViewModel :

  • আপনি জীবনচক্র-সচেতন উপায়ে UI-সম্পর্কিত ডেটা সঞ্চয় এবং পরিচালনা করতে ViewModel ক্লাস ব্যবহার করেন। ViewModel ক্লাস ডেটা ডিভাইস-কনফিগারেশন পরিবর্তন যেমন স্ক্রীন ঘূর্ণন এবং কীবোর্ড প্রাপ্যতা পরিবর্তনের মতো টিকে থাকতে দেয়।
  • আপনি ViewModelFactory ক্লাসটি ইনস্ট্যান্টিয়েট করতে এবং ViewModel অবজেক্টটি ফেরত দিতে ব্যবহার করেন যা কনফিগারেশন পরিবর্তন থেকে বেঁচে থাকে।

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

  • কোটলিনে কীভাবে বেসিক অ্যান্ড্রয়েড অ্যাপ তৈরি করবেন।
  • আপনার অ্যাপে নেভিগেশন বাস্তবায়নের জন্য কীভাবে নেভিগেশন গ্রাফ ব্যবহার করবেন।
  • কীভাবে আপনার অ্যাপের গন্তব্যের মধ্যে নেভিগেট করতে কোড যোগ করবেন এবং নেভিগেশন গন্তব্যগুলির মধ্যে ডেটা পাস করবেন।
  • কার্যকলাপ এবং খণ্ড জীবনচক্র কিভাবে কাজ করে।
  • Android স্টুডিওতে Logcat ব্যবহার করে কীভাবে একটি অ্যাপে লগিং তথ্য যোগ করবেন এবং লগগুলি পড়তে হবে।

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

  • সুপারিশকৃত অ্যান্ড্রয়েড অ্যাপ আর্কিটেকচার কীভাবে ব্যবহার করবেন।
  • আপনার অ্যাপে Lifecycle , ViewModel এবং ViewModelFactory ক্লাসগুলি কীভাবে ব্যবহার করবেন।
  • ডিভাইস-কনফিগারেশন পরিবর্তনের মাধ্যমে কিভাবে UI ডেটা ধরে রাখা যায়।
  • ফ্যাক্টরি মেথড ডিজাইন প্যাটার্ন কি এবং কিভাবে ব্যবহার করতে হয়।
  • ViewModelProvider.Factory ইন্টারফেস ব্যবহার করে কিভাবে একটি ViewModel অবজেক্ট তৈরি করবেন।

আপনি কি করবেন

  • অ্যাপের ডেটা সংরক্ষণ করতে অ্যাপটিতে একটি ViewModel যোগ করুন যাতে ডেটা কনফিগারেশন পরিবর্তন থেকে বেঁচে থাকে।
  • কনস্ট্রাক্টর প্যারামিটার সহ একটি ViewModel অবজেক্টকে ইনস্ট্যান্ট করতে ViewModelFactory এবং ফ্যাক্টরি-পদ্ধতি ডিজাইন প্যাটার্ন ব্যবহার করুন।

পাঠ 5 কোডল্যাবগুলিতে, আপনি স্টার্টার কোড দিয়ে শুরু করে GuessTheWord অ্যাপ তৈরি করেন। GuessTheWord হল একটি দুই-প্লেয়ার চ্যারেড -স্টাইলের খেলা, যেখানে খেলোয়াড়রা সম্ভাব্য সর্বোচ্চ স্কোর অর্জন করতে সহযোগিতা করে।

প্রথম প্লেয়ার অ্যাপে থাকা শব্দগুলি দেখে এবং পালাক্রমে প্রতিটি কাজ করে, নিশ্চিত করে যে শব্দটি দ্বিতীয় প্লেয়ারকে না দেখায়৷ দ্বিতীয় খেলোয়াড় শব্দটি অনুমান করার চেষ্টা করে।

গেমটি খেলতে, প্রথম প্লেয়ার ডিভাইসে অ্যাপটি খোলে এবং একটি শব্দ দেখতে পায়, উদাহরণস্বরূপ "গিটার", যেমনটি নীচের স্ক্রিনশটে দেখানো হয়েছে৷

প্রথম খেলোয়াড় শব্দটি কার্যকর করে, সতর্কতা অবলম্বন করে যে শব্দটি নিজেই না বলে।

  • যখন দ্বিতীয় প্লেয়ার সঠিকভাবে শব্দটি অনুমান করে, প্রথম প্লেয়ার Got It বোতাম টিপে, যা এক দ্বারা গণনা বৃদ্ধি করে এবং পরবর্তী শব্দটি দেখায়।
  • যদি দ্বিতীয় প্লেয়ার শব্দটি অনুমান করতে না পারে, প্রথম খেলোয়াড় স্কিপ বোতাম টিপে, যা গণনা এক দ্বারা হ্রাস করে এবং পরবর্তী শব্দে চলে যায়।
  • গেমটি শেষ করতে, এন্ড গেম বোতাম টিপুন। (এই কার্যকারিতা সিরিজের প্রথম কোডল্যাবের জন্য স্টার্টার কোডে নেই।)

এই টাস্কে, আপনি স্টার্টার অ্যাপটি ডাউনলোড করে চালান এবং কোডটি পরীক্ষা করুন।

ধাপ 1: শুরু করুন

  1. GuessTheWord স্টার্টার কোড ডাউনলোড করুন এবং অ্যান্ড্রয়েড স্টুডিওতে প্রকল্পটি খুলুন।
  2. একটি অ্যান্ড্রয়েড-চালিত ডিভাইসে বা এমুলেটরে অ্যাপটি চালান।
  3. বোতামগুলি আলতো চাপুন। লক্ষ্য করুন যে Skip বোতামটি পরবর্তী শব্দটি প্রদর্শন করে এবং একটি দ্বারা স্কোর হ্রাস করে এবং Got It বোতামটি পরবর্তী শব্দটি দেখায় এবং একটি দ্বারা স্কোর বৃদ্ধি করে। শেষ গেম বোতামটি বাস্তবায়িত হয় না, তাই আপনি এটিতে ট্যাপ করলে কিছুই ঘটে না।

ধাপ 2: একটি কোড ওয়াকথ্রু করুন

  1. অ্যান্ড্রয়েড স্টুডিওতে, অ্যাপটি কীভাবে কাজ করে তার অনুভূতি পেতে কোডটি অন্বেষণ করুন।
  2. নীচে বর্ণিত ফাইলগুলি দেখতে ভুলবেন না, যা বিশেষভাবে গুরুত্বপূর্ণ।

MainActivity.kt

এই ফাইলটিতে শুধুমাত্র ডিফল্ট, টেমপ্লেট-উত্পন্ন কোড রয়েছে।

res/layout/main_activity.xml

এই ফাইলটিতে অ্যাপের প্রধান লেআউট রয়েছে। ব্যবহারকারী অ্যাপের মাধ্যমে নেভিগেট করার সাথে সাথে NavHostFragment অন্যান্য টুকরা হোস্ট করে।

UI খণ্ড

com.example.android.guesstheword.screens প্যাকেজের অধীনে তিনটি ভিন্ন প্যাকেজে স্টার্টার কোডের তিনটি খণ্ড রয়েছে:

  • শিরোনাম পর্দার জন্য title/TitleFragment
  • গেম স্ক্রিনের জন্য game/GameFragment
  • স্কোর স্ক্রিনের জন্য score/ScoreFragment

screens/title/TitleFragment.kt

টাইটেল ফ্র্যাগমেন্ট হল প্রথম স্ক্রীন যা অ্যাপটি চালু হলে প্রদর্শিত হয়। গেম স্ক্রিনে নেভিগেট করতে একটি ক্লিক হ্যান্ডলার প্লে বোতামে সেট করা আছে।

screens/game/GameFragment.kt

এটি প্রধান খণ্ড, যেখানে গেমের বেশিরভাগ ক্রিয়া সংঘটিত হয়:

  • চলক বর্তমান শব্দ এবং বর্তমান স্কোর জন্য সংজ্ঞায়িত করা হয়.
  • resetList() পদ্ধতির ভিতরে সংজ্ঞায়িত wordList হল গেমে ব্যবহার করা শব্দের নমুনা তালিকা।
  • onSkip() পদ্ধতি হল Skip বাটনের জন্য ক্লিক হ্যান্ডলার। এটি স্কোর 1 দ্বারা হ্রাস করে, তারপর nextWord() পদ্ধতি ব্যবহার করে পরবর্তী শব্দ প্রদর্শন করে।
  • onCorrect() পদ্ধতি হল Got It বোতামের জন্য ক্লিক হ্যান্ডলার। এই পদ্ধতিটি onSkip() পদ্ধতির অনুরূপভাবে প্রয়োগ করা হয়। একমাত্র পার্থক্য হল এই পদ্ধতিটি বিয়োগের পরিবর্তে স্কোরে 1 যোগ করে।

screens/score/ScoreFragment.kt

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

res/navigation/main_navigation.xml

নেভিগেশন গ্রাফ দেখায় কিভাবে খণ্ডগুলো নেভিগেশনের মাধ্যমে সংযুক্ত থাকে:

  • শিরোনাম খণ্ড থেকে, ব্যবহারকারী গেম খণ্ডে নেভিগেট করতে পারেন।
  • গেমের খণ্ড থেকে, ব্যবহারকারী স্কোর খণ্ডে নেভিগেট করতে পারেন।
  • স্কোর ফ্র্যাগমেন্ট থেকে, ব্যবহারকারী গেমের খণ্ডে ফিরে যেতে পারেন।

এই টাস্কে, আপনি GuessTheWord স্টার্টার অ্যাপে সমস্যাগুলি খুঁজে পান।

  1. স্টার্টার কোডটি চালান এবং প্রতিটি শব্দের পরে স্কিপ বা গট ইট ট্যাপ করে কয়েকটি শব্দের মাধ্যমে গেমটি খেলুন।
  2. গেম স্ক্রীন এখন একটি শব্দ এবং বর্তমান স্কোর দেখায়। ডিভাইস বা এমুলেটর ঘোরানোর মাধ্যমে পর্দার অভিযোজন পরিবর্তন করুন। লক্ষ্য করুন বর্তমান স্কোর হারিয়ে গেছে।
  3. আরও কয়েকটি শব্দের মাধ্যমে গেমটি চালান। কিছু স্কোর সহ গেম স্ক্রীন প্রদর্শিত হলে, অ্যাপটি বন্ধ করুন এবং পুনরায় খুলুন। লক্ষ্য করুন যে গেমটি শুরু থেকে পুনরায় চালু হচ্ছে, কারণ অ্যাপের অবস্থা সংরক্ষণ করা হয়নি।
  4. কয়েকটি শব্দের মাধ্যমে গেমটি খেলুন, তারপরে শেষ গেম বোতামটি আলতো চাপুন। লক্ষ্য করুন যে কিছুই ঘটে না।

অ্যাপে সমস্যা:

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

আপনি এই কোডল্যাবে যে অ্যাপ আর্কিটেকচার উপাদানগুলি সম্পর্কে শিখছেন তা ব্যবহার করে আপনি এই সমস্যাগুলি সমাধান করতে পারেন৷

অ্যাপ আর্কিটেকচার

অ্যাপ আর্কিটেকচার হল আপনার অ্যাপের ক্লাস ডিজাইন করার একটি উপায়, এবং তাদের মধ্যে সম্পর্ক, যেমন কোডটি সংগঠিত, নির্দিষ্ট পরিস্থিতিতে ভাল কাজ করে এবং কাজ করা সহজ। চারটি কোডল্যাবের এই সেটে, আপনি GuessTheWord অ্যাপে যে উন্নতিগুলি করেন তা Android অ্যাপের আর্কিটেকচার নির্দেশিকা অনুসরণ করে এবং আপনি Android আর্কিটেকচার উপাদান ব্যবহার করেন। অ্যান্ড্রয়েড অ্যাপের আর্কিটেকচারটি এমভিভিএম (মডেল-ভিউ-ভিউ মডেল) আর্কিটেকচারাল প্যাটার্নের মতো।

GuessTheWord অ্যাপ উদ্বেগের নকশা নীতির বিচ্ছেদ অনুসরণ করে এবং প্রতিটি ক্লাসে আলাদা উদ্বেগের সমাধানের সাথে ক্লাসে বিভক্ত। পাঠের এই প্রথম কোডল্যাবে, আপনি যে ক্লাসগুলির সাথে কাজ করেন তা হল একটি UI কন্ট্রোলার, একটি ViewModel এবং একটি ViewModelFactory

UI কন্ট্রোলার

একটি UI কন্ট্রোলার হল একটি UI-ভিত্তিক ক্লাস যেমন Activity বা Fragment । একটি UI কন্ট্রোলারে শুধুমাত্র যুক্তি থাকা উচিত যা UI এবং অপারেটিং-সিস্টেম ইন্টারঅ্যাকশনগুলি পরিচালনা করে যেমন ভিউ প্রদর্শন করা এবং ব্যবহারকারীর ইনপুট ক্যাপচার করা। UI কন্ট্রোলারে ডিসিশন-মেকিং লজিক রাখবেন না, যেমন লজিক যা প্রদর্শনের জন্য টেক্সট নির্ধারণ করে।

GuessTheWord স্টার্টার কোডে, UI কন্ট্রোলার হল তিনটি খণ্ড: GameFragment , ScoreFragment, এবং TitleFragment । "উদ্বেগের বিচ্ছেদ" ডিজাইনের নীতি অনুসরণ করে, GameFragment শুধুমাত্র গেমের উপাদানগুলিকে স্ক্রিনে আঁকার জন্য এবং ব্যবহারকারী কখন বোতামগুলি ট্যাপ করে তা জানার জন্য দায়ী এবং এর বেশি কিছু নয়। যখন ব্যবহারকারী একটি বোতামে ট্যাপ করে, তখন এই তথ্যটি GameViewModel এ পাঠানো হয়।

মডেল দেখুন

একটি ViewModel ViewModel এর সাথে যুক্ত একটি খণ্ড বা কার্যকলাপে প্রদর্শিত ডেটা ধারণ করে। একটি ViewModel UI কন্ট্রোলার দ্বারা প্রদর্শিত ডেটা প্রস্তুত করতে ডেটাতে সাধারণ গণনা এবং রূপান্তর করতে পারে। এই আর্কিটেকচারে, ViewModel সিদ্ধান্ত গ্রহণের কাজ করে।

GameViewModel স্কোর মান, শব্দের তালিকা এবং বর্তমান শব্দের মতো ডেটা ধারণ করে, কারণ এটি স্ক্রিনে প্রদর্শিত ডেটা। GameViewModel ডেটার বর্তমান অবস্থা কী তা নির্ধারণ করতে সহজ গণনা সম্পাদন করার জন্য ব্যবসায়িক যুক্তিও রয়েছে।

মডেল ফ্যাক্টরি দেখুন

একটি ViewModelFactory কনস্ট্রাক্টর প্যারামিটার সহ বা ছাড়াই ViewModel অবজেক্টগুলিকে ইনস্ট্যান্টিয়েট করে।

পরবর্তী কোডল্যাবগুলিতে, আপনি অন্যান্য অ্যান্ড্রয়েড আর্কিটেকচার উপাদান সম্পর্কে শিখবেন যেগুলি UI কন্ট্রোলার এবং ViewModel এর সাথে সম্পর্কিত।

ViewModel ক্লাসটি UI-সম্পর্কিত ডেটা সংরক্ষণ এবং পরিচালনা করার জন্য ডিজাইন করা হয়েছে। এই অ্যাপে, প্রতিটি ViewModel একটি খণ্ডের সাথে যুক্ত।

এই টাস্কে, আপনি আপনার অ্যাপে আপনার প্রথম ViewModel যোগ করেন, GameFragment জন্য GameViewModel । আপনি এটাও শিখবেন যে ViewModel জীবনচক্র-সচেতন।

ধাপ 1: GameViewModel ক্লাস যোগ করুন

  1. build.gradle(module:app) ফাইলটি খুলুন। dependencies ব্লকের ভিতরে, ViewModel জন্য Gradle নির্ভরতা যোগ করুন।

    আপনি যদি লাইব্রেরির সর্বশেষ সংস্করণ ব্যবহার করেন, তাহলে সমাধান অ্যাপটি প্রত্যাশা অনুযায়ী কম্পাইল করা উচিত। যদি এটি না হয়, সমস্যাটি সমাধান করার চেষ্টা করুন, অথবা নীচে দেখানো সংস্করণে ফিরে যান৷
//ViewModel
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
  1. প্যাকেজ screens/game/ ফোল্ডারে, GameViewModel নামে একটি নতুন কোটলিন ক্লাস তৈরি করুন।
  2. GameViewModel ক্লাসটিকে বিমূর্ত ক্লাস ViewModel প্রসারিত করুন।
  3. ViewModel কীভাবে লাইফসাইকেল-সচেতন তা আরও ভালভাবে বুঝতে সাহায্য করার জন্য, log স্টেটমেন্ট সহ একটি init ব্লক যোগ করুন।
class GameViewModel : ViewModel() {
   init {
       Log.i("GameViewModel", "GameViewModel created!")
   }
}

ধাপ 2: অনক্লিয়ারড() ওভাররাইড করুন এবং লগিং যোগ করুন

সংশ্লিষ্ট খণ্ডটি বিচ্ছিন্ন হলে বা কার্যকলাপ শেষ হলে ViewModel ধ্বংস হয়ে যায়। ViewModel ধ্বংস হওয়ার ঠিক আগে, onCleared() কলব্যাককে রিসোর্স পরিষ্কার করতে বলা হয়।

  1. GameViewModel ক্লাসে, onCleared() পদ্ধতিটি ওভাররাইড করুন।
  2. GameViewModel জীবনচক্র ট্র্যাক করতে onCleared() ভিতরে একটি লগ স্টেটমেন্ট যোগ করুন।
override fun onCleared() {
   super.onCleared()
   Log.i("GameViewModel", "GameViewModel destroyed!")
}

ধাপ 3: গেমের টুকরোটির সাথে GameViewModel যুক্ত করুন

একটি ViewModel একটি UI কন্ট্রোলারের সাথে যুক্ত হওয়া প্রয়োজন৷ দুটিকে সংযুক্ত করতে, আপনি UI কন্ট্রোলারের ভিতরে ViewModel একটি রেফারেন্স তৈরি করেন।

এই ধাপে, আপনি সংশ্লিষ্ট UI কন্ট্রোলারের ভিতরে GameViewModel এর একটি রেফারেন্স তৈরি করেন, যা হল GameFragment

  1. GameFragment ক্লাসে, ক্লাস ভেরিয়েবল হিসাবে শীর্ষ স্তরে GameViewModel ধরণের একটি ক্ষেত্র যুক্ত করুন।
private lateinit var viewModel: GameViewModel

ধাপ 4: ভিউ মডেল শুরু করুন

কনফিগারেশন পরিবর্তনের সময় যেমন স্ক্রিন ঘূর্ণন, UI কন্ট্রোলার যেমন টুকরোগুলি পুনরায় তৈরি করা হয়। যাইহোক, ViewModel দৃষ্টান্তগুলি বেঁচে থাকে। আপনি যদি ViewModel ক্লাস ব্যবহার করে ViewModel উদাহরণ তৈরি করেন, প্রতিবার খণ্ডটি পুনরায় তৈরি করার সময় একটি নতুন অবজেক্ট তৈরি করা হয়। পরিবর্তে, একটি ViewModelProvider ব্যবহার করে ViewModel উদাহরণ তৈরি করুন।

কিভাবে ViewModelProvider কাজ করে:

  • ViewModelProvider একটি বিদ্যমান ViewModel প্রদান করে যদি একটি বিদ্যমান থাকে, অথবা এটি একটি নতুন তৈরি করে যদি এটি ইতিমধ্যে বিদ্যমান না থাকে।
  • ViewModelProvider প্রদত্ত সুযোগ (একটি কার্যকলাপ বা একটি খণ্ড) এর সাথে মিল রেখে একটি ViewModel উদাহরণ তৈরি করে।
  • যতক্ষণ সুযোগ জীবিত থাকে ততক্ষণ তৈরি করা ViewModel ধরে রাখা হয়। উদাহরণস্বরূপ, যদি স্কোপটি একটি খণ্ড হয়, তাহলে খণ্ডটি বিচ্ছিন্ন না হওয়া পর্যন্ত ViewModel বজায় রাখা হয়।

একটি ViewModelProvider তৈরি করতে ViewModelProviders.of() পদ্ধতি ব্যবহার করে ViewModel শুরু করুন:

  1. GameFragment ক্লাসে, viewModel ভেরিয়েবল শুরু করুন। বাইন্ডিং ভেরিয়েবলের সংজ্ঞার পরে, onCreateView() এর ভিতরে এই কোডটি রাখুন। ViewModelProviders.of() পদ্ধতিটি ব্যবহার করুন এবং সংশ্লিষ্ট GameFragment প্রসঙ্গ এবং GameViewModel ক্লাসে পাস করুন।
  2. ViewModel অবজেক্টের শুরুর উপরে, ViewModelProviders.of() পদ্ধতি কল লগ করার জন্য একটি লগ স্টেটমেন্ট যোগ করুন।
Log.i("GameFragment", "Called ViewModelProviders.of")
viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)
  1. অ্যাপটি চালান। অ্যান্ড্রয়েড স্টুডিওতে, লগক্যাট প্যানটি খুলুন এবং Game ফিল্টার করুন। আপনার ডিভাইস বা এমুলেটরে প্লে বোতামে আলতো চাপুন। গেমের পর্দা খোলে।

    Logcat-এ দেখানো হয়েছে, GameFragment এর onCreateView() পদ্ধতিটি GameViewModel তৈরি করতে ViewModelProviders.of() পদ্ধতিকে কল করে। লগিং বিবৃতি যা আপনি GameFragment এবং GameViewModel এ যোগ করেছেন তা Logcat-এ দেখা যাচ্ছে।

  1. আপনার ডিভাইস বা এমুলেটরে স্বয়ংক্রিয়-ঘোরান সেটিং সক্ষম করুন এবং কয়েকবার স্ক্রিন অভিযোজন পরিবর্তন করুন। GameFragment প্রতিবার ধ্বংস করা হয় এবং পুনরায় তৈরি করা হয়, তাই প্রতিবার ViewModelProviders.of() বলা হয়। কিন্তু GameViewModel শুধুমাত্র একবার তৈরি করা হয়, এবং এটি প্রতিটি কলের জন্য পুনরায় তৈরি বা ধ্বংস করা হয় না।
I/GameFragment: Called ViewModelProviders.of
I/GameViewModel: GameViewModel created!
I/GameFragment: Called ViewModelProviders.of
I/GameFragment: Called ViewModelProviders.of
I/GameFragment: Called ViewModelProviders.of
  1. গেম থেকে প্রস্থান করুন বা গেমের অংশ থেকে নেভিগেট করুন। GameFragment ধ্বংস হয়ে গেছে। সংশ্লিষ্ট GameViewModel টিও ধ্বংস হয়ে গেছে এবং কলব্যাক onCleared() বলা হয়।
I/GameFragment: Called ViewModelProviders.of
I/GameViewModel: GameViewModel created!
I/GameFragment: Called ViewModelProviders.of
I/GameFragment: Called ViewModelProviders.of
I/GameFragment: Called ViewModelProviders.of
I/GameViewModel: GameViewModel destroyed!

ViewModel কনফিগারেশন পরিবর্তনগুলি থেকে বেঁচে থাকে, তাই এটি এমন ডেটার জন্য একটি ভাল জায়গা যা কনফিগারেশন পরিবর্তনগুলি থেকে বাঁচতে হবে:

  • স্ক্রিনে দেখানোর জন্য ডেটা রাখুন এবং সেই ডেটা প্রক্রিয়া করার জন্য কোডটি ViewModel রাখুন।
  • ViewModel কখনই টুকরো, ক্রিয়াকলাপ বা দৃশ্যের উল্লেখ থাকা উচিত নয়, কারণ ক্রিয়াকলাপ, টুকরো এবং দৃশ্যগুলি কনফিগারেশন পরিবর্তনগুলিকে বাঁচায় না৷

তুলনা করার জন্য, আপনি ViewModel যোগ করার আগে এবং আপনি ViewModel যোগ করার পরে স্টার্টার অ্যাপে GameFragment UI ডেটা কীভাবে পরিচালনা করা হয় তা এখানে রয়েছে:

  • আপনি ViewModel যোগ করার আগে:
    অ্যাপটি যখন স্ক্রিন ঘূর্ণনের মতো কনফিগারেশন পরিবর্তনের মধ্য দিয়ে যায়, তখন গেমের খণ্ডটি ধ্বংস হয়ে আবার তৈরি হয়। ডেটা হারিয়ে গেছে।
  • আপনি ViewModel যোগ করার পরে এবং গেমের খণ্ডের UI ডেটা ViewModel এ সরানোর পরে:
    খণ্ডটির প্রদর্শনের জন্য প্রয়োজনীয় সমস্ত ডেটা এখন ViewModel । অ্যাপটি যখন কনফিগারেশন পরিবর্তনের মধ্য দিয়ে যায়, তখন ViewModel টিকে থাকে এবং ডেটা বজায় থাকে।

এই টাস্কে, আপনি ডেটা প্রক্রিয়া করার পদ্ধতি সহ অ্যাপের UI ডেটা GameViewModel ক্লাসে স্থানান্তরিত করেন। আপনি এটি করেন যাতে কনফিগারেশন পরিবর্তনের সময় ডেটা বজায় থাকে।

ধাপ 1: ViewModel-এ ডেটা ক্ষেত্র এবং ডেটা প্রসেসিং সরান

GameFragment থেকে GameViewModel এ নিম্নলিখিত ডেটা ক্ষেত্র এবং পদ্ধতিগুলি সরান:

  1. word , score , এবং wordList ডেটা ক্ষেত্রগুলি সরান। নিশ্চিত করুন যে word এবং score private নয়।

    বাইন্ডিং ভেরিয়েবল, GameFragmentBinding সরান না, কারণ এতে ভিউগুলির রেফারেন্স রয়েছে। এই ভেরিয়েবলটি লেআউটকে স্ফীত করতে, ক্লিক শ্রোতাদের সেট আপ করতে এবং স্ক্রিনে ডেটা প্রদর্শন করতে ব্যবহৃত হয়—খণ্ডটির দায়িত্ব।
  2. resetList() এবং nextWord() পদ্ধতিগুলি সরান। এই পদ্ধতিগুলি স্ক্রিনে কোন শব্দ দেখাবে তা নির্ধারণ করে।
  3. onCreateView() পদ্ধতির ভিতর থেকে, মেথড কলগুলিকে resetList() এবং nextWord()GameViewModel এর init ব্লকে সরান।

    এই পদ্ধতিগুলি অবশ্যই init ব্লকে থাকতে হবে, কারণ ViewModel তৈরি করার সময় আপনার শব্দ তালিকা পুনরায় সেট করা উচিত, প্রতিবার খণ্ডটি তৈরি করার সময় নয়। আপনি GameFragment এর init ব্লকে লগ স্টেটমেন্ট মুছে ফেলতে পারেন।

GameFragment onSkip() এবং onCorrect() ক্লিক হ্যান্ডলারগুলিতে ডেটা প্রক্রিয়াকরণ এবং UI আপডেট করার জন্য কোড থাকে। UI আপডেট করার কোডটি ফ্র্যাগমেন্টে থাকা উচিত, তবে ডেটা প্রক্রিয়াকরণের কোডটি ViewModel এ সরানো দরকার।

আপাতত, উভয় জায়গায় অভিন্ন পদ্ধতি রাখুন:

  1. GameFragment থেকে GameViewModelonSkip() এবং onCorrect() পদ্ধতি অনুলিপি করুন।
  2. GameViewModel এ, নিশ্চিত করুন যে onSkip() এবং onCorrect() পদ্ধতিগুলি private নয়, কারণ আপনি এই পদ্ধতিগুলিকে খণ্ড থেকে উল্লেখ করবেন।

রিফ্যাক্টরিংয়ের পরে GameViewModel ক্লাসের কোড এখানে রয়েছে:

class GameViewModel : ViewModel() {
   // The current word
   var word = ""
   // The current score
   var score = 0
   // The list of words - the front of the list is the next word to guess
   private lateinit var wordList: MutableList<String>

   /**
    * Resets the list of words and randomizes the order
    */
   private fun resetList() {
       wordList = mutableListOf(
               "queen",
               "hospital",
               "basketball",
               "cat",
               "change",
               "snail",
               "soup",
               "calendar",
               "sad",
               "desk",
               "guitar",
               "home",
               "railway",
               "zebra",
               "jelly",
               "car",
               "crow",
               "trade",
               "bag",
               "roll",
               "bubble"
       )
       wordList.shuffle()
   }

   init {
       resetList()
       nextWord()
       Log.i("GameViewModel", "GameViewModel created!")
   }
   /**
    * Moves to the next word in the list
    */
   private fun nextWord() {
       if (!wordList.isEmpty()) {
           //Select and remove a word from the list
           word = wordList.removeAt(0)
       }
       updateWordText()
       updateScoreText()
   }
 /** Methods for buttons presses **/
   fun onSkip() {
       if (!wordList.isEmpty()) {
           score--
       }
       nextWord()
   }

   fun onCorrect() {
       if (!wordList.isEmpty()) {
           score++
       }
       nextWord()
   }

   override fun onCleared() {
       super.onCleared()
       Log.i("GameViewModel", "GameViewModel destroyed!")
   }
}

রিফ্যাক্টরিংয়ের পরে GameFragment ক্লাসের কোড এখানে রয়েছে:

/**
* Fragment where the game is played
*/
class GameFragment : Fragment() {


   private lateinit var binding: GameFragmentBinding


   private lateinit var viewModel: GameViewModel


   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                             savedInstanceState: Bundle?): View? {

       // Inflate view and obtain an instance of the binding class
       binding = DataBindingUtil.inflate(
               inflater,
               R.layout.game_fragment,
               container,
               false
       )

       Log.i("GameFragment", "Called ViewModelProviders.of")
       viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)

       binding.correctButton.setOnClickListener { onCorrect() }
       binding.skipButton.setOnClickListener { onSkip() }
       updateScoreText()
       updateWordText()
       return binding.root

   }


   /** Methods for button click handlers **/

   private fun onSkip() {
       if (!wordList.isEmpty()) {
           score--
       }
       nextWord()
   }

   private fun onCorrect() {
       if (!wordList.isEmpty()) {
           score++
       }
       nextWord()
   }


   /** Methods for updating the UI **/

   private fun updateWordText() {
       binding.wordText.text = word
   }

   private fun updateScoreText() {
       binding.scoreText.text = score.toString()
   }
}

ধাপ 2: গেমফ্র্যাগমেন্টে ক্লিক হ্যান্ডলার এবং ডেটা ক্ষেত্রের রেফারেন্স আপডেট করুন

  1. GameFragment এ, onSkip() এবং onCorrect() পদ্ধতি আপডেট করুন। স্কোর আপডেট করতে কোডটি সরান এবং পরিবর্তে viewModel এ সংশ্লিষ্ট onSkip() এবং onCorrect() পদ্ধতিতে কল করুন।
  2. যেহেতু আপনি nextWord() পদ্ধতিটি ViewModel এ স্থানান্তর করেছেন, গেমের খণ্ডটি আর এটি অ্যাক্সেস করতে পারবে না।

    GameFragment এ, onSkip() এবং onCorrect() পদ্ধতিতে, updateScoreText() এবং updateWordText() দিয়ে nextWord() এ কলটি প্রতিস্থাপন করুন। এই পদ্ধতিগুলি স্ক্রিনে ডেটা প্রদর্শন করে।
private fun onSkip() {
   viewModel.onSkip()
   updateWordText()
   updateScoreText()
}
private fun onCorrect() {
   viewModel.onCorrect()
   updateScoreText()
   updateWordText()
}
  1. GameFragment এ, GameViewModel ভেরিয়েবল ব্যবহার করতে score এবং word ভেরিয়েবল আপডেট করুন, কারণ এই ভেরিয়েবলগুলি এখন GameViewModel এ রয়েছে।
private fun updateWordText() {
   binding.wordText.text = viewModel.word
}

private fun updateScoreText() {
   binding.scoreText.text = viewModel.score.toString()
}
  1. GameViewModel এ, nextWord() পদ্ধতির ভিতরে, updateWordText() এবং updateScoreText() পদ্ধতিতে কলগুলি সরিয়ে দিন। এই পদ্ধতিগুলি এখন GameFragment থেকে বলা হচ্ছে।
  2. অ্যাপটি তৈরি করুন এবং নিশ্চিত করুন যে কোনও ত্রুটি নেই। আপনার যদি ত্রুটি থাকে তবে প্রকল্পটি পরিষ্কার করুন এবং পুনর্নির্মাণ করুন।
  3. অ্যাপটি চালান এবং কিছু শব্দের মাধ্যমে গেমটি খেলুন। আপনি যখন গেম স্ক্রিনে থাকবেন, ডিভাইসটি ঘোরান। লক্ষ্য করুন যে অরিয়েন্টেশন পরিবর্তনের পরে বর্তমান স্কোর এবং বর্তমান শব্দটি ধরে রাখা হয়েছে।

দারুণ কাজ! এখন আপনার অ্যাপের সমস্ত ডেটা একটি ViewModel এ সংরক্ষণ করা হয়েছে, তাই কনফিগারেশন পরিবর্তনের সময় এটি বজায় রাখা হয়।

এই টাস্কে, আপনি এন্ড গেম বোতামের জন্য ক্লিক লিসেনার বাস্তবায়ন করেন।

  1. GameFragment এ, onEndGame() নামে একটি পদ্ধতি যোগ করুন। ব্যবহারকারী যখন এন্ড গেম বোতামে ট্যাপ করবে তখন onEndGame() পদ্ধতিটি কল করা হবে।
private fun onEndGame() {
   }
  1. GameFragment এ, onCreateView() পদ্ধতির ভিতরে, সেই কোডটি সনাক্ত করুন যা Got It এবং Skip বোতামগুলির জন্য ক্লিক শ্রোতাদের সেট করে। এই দুটি লাইনের ঠিক নীচে, শেষ গেম বোতামের জন্য একটি ক্লিক শ্রোতা সেট করুন। বাইন্ডিং ভেরিয়েবল, binding ব্যবহার করুন। ক্লিক শ্রোতার ভিতরে, onEndGame() পদ্ধতিতে কল করুন।
binding.endGameButton.setOnClickListener { onEndGame() }
  1. GameFragment এ, স্কোর স্ক্রিনে অ্যাপটি নেভিগেট করতে gameFinished() নামে একটি পদ্ধতি যোগ করুন। Safe Args ব্যবহার করে আর্গুমেন্ট হিসেবে স্কোর পাস করুন।
/**
* Called when the game is finished
*/
private fun gameFinished() {
   Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
   val action = GameFragmentDirections.actionGameToScore()
   action.score = viewModel.score
   NavHostFragment.findNavController(this).navigate(action)
}
  1. onEndGame() পদ্ধতিতে, gameFinished() পদ্ধতিতে কল করুন।
private fun onEndGame() {
   gameFinished()
}
  1. অ্যাপটি চালান, গেম খেলুন এবং কিছু শব্দের মাধ্যমে সাইকেল করুন। এন্ড গেম বোতামে ট্যাপ করুন। লক্ষ্য করুন যে অ্যাপটি স্কোর স্ক্রিনে নেভিগেট করে, কিন্তু চূড়ান্ত স্কোর প্রদর্শিত হয় না। আপনি পরবর্তী টাস্কে এটি ঠিক করুন।

যখন ব্যবহারকারী গেমটি শেষ করে, তখন ScoreFragment স্কোর দেখায় না। আপনি ScoreFragment দ্বারা প্রদর্শিত স্কোর ধরে রাখার জন্য একটি ViewModel চান। আপনি ফ্যাক্টরি পদ্ধতি প্যাটার্ন ব্যবহার করে ViewModel আরম্ভ করার সময় স্কোর মান পাস করবেন।

ফ্যাক্টরি মেথড প্যাটার্ন হল একটি সৃজনশীল ডিজাইন প্যাটার্ন যা বস্তু তৈরি করতে ফ্যাক্টরি পদ্ধতি ব্যবহার করে। একটি কারখানা পদ্ধতি হল একটি পদ্ধতি যা একই শ্রেণীর একটি উদাহরণ প্রদান করে।

এই টাস্কে, আপনি স্কোর ফ্র্যাগমেন্টের জন্য একটি প্যারামিটারাইজড কনস্ট্রাক্টর সহ একটি ViewModel তৈরি করেন এবং ViewModel ইনস্ট্যান্টিয়েট করার জন্য একটি ফ্যাক্টরি পদ্ধতি।

  1. score প্যাকেজের অধীনে, ScoreViewModel নামে একটি নতুন কোটলিন ক্লাস তৈরি করুন। এই ক্লাসটি স্কোর ফ্র্যাগমেন্টের জন্য ViewModel হবে।
  2. ViewModel. থেকে ScoreViewModel ক্লাস প্রসারিত করুন। চূড়ান্ত স্কোরের জন্য একটি কনস্ট্রাক্টর প্যারামিটার যোগ করুন। লগ স্টেটমেন্ট সহ একটি init ব্লক যোগ করুন।
  3. ScoreViewModel ক্লাসে, চূড়ান্ত স্কোর সংরক্ষণ করতে score নামে একটি ভেরিয়েবল যোগ করুন।
class ScoreViewModel(finalScore: Int) : ViewModel() {
   // The final score
   var score = finalScore
   init {
       Log.i("ScoreViewModel", "Final score is $finalScore")
   }
}
  1. score প্যাকেজের অধীনে, ScoreViewModelFactory নামে আরেকটি কোটলিন ক্লাস তৈরি করুন। এই শ্রেণীটি ScoreViewModel অবজেক্টকে ইনস্ট্যান্ট করার জন্য দায়ী থাকবে।
  2. ViewModelProvider.Factory থেকে ScoreViewModelFactory ক্লাস প্রসারিত করুন। চূড়ান্ত স্কোরের জন্য একটি কনস্ট্রাক্টর প্যারামিটার যোগ করুন।
class ScoreViewModelFactory(private val finalScore: Int) : ViewModelProvider.Factory {
}
  1. ScoreViewModelFactory এ, অ্যান্ড্রয়েড স্টুডিও একটি অবাস্তব বিমূর্ত সদস্য সম্পর্কে একটি ত্রুটি দেখায়। ত্রুটি সমাধান করতে, create() পদ্ধতিটি ওভাররাইড করুন। create() পদ্ধতিতে, নতুন নির্মিত ScoreViewModel অবজেক্টটি ফেরত দিন।
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
   if (modelClass.isAssignableFrom(ScoreViewModel::class.java)) {
       return ScoreViewModel(finalScore) as T
   }
   throw IllegalArgumentException("Unknown ViewModel class")
}
  1. ScoreFragment এ, ScoreViewModel এবং ScoreViewModelFactory জন্য ক্লাস ভেরিয়েবল তৈরি করুন।
private lateinit var viewModel: ScoreViewModel
private lateinit var viewModelFactory: ScoreViewModelFactory
  1. ScoreFragment এ, onCreateView() ভিতরে, binding ভেরিয়েবল শুরু করার পর, viewModelFactory আরম্ভ করুন। ScoreViewModelFactory ব্যবহার করুন। ScoreViewModelFactory() এ কনস্ট্রাক্টর প্যারামিটার হিসাবে আর্গুমেন্ট বান্ডেল থেকে চূড়ান্ত স্কোর পাস করুন।
viewModelFactory = ScoreViewModelFactory(ScoreFragmentArgs.fromBundle(arguments!!).score)
  1. onCreateView( ), viewModelFactory আরম্ভ করার পরে, viewModel অবজেক্ট আরম্ভ করুন। ViewModelProviders.of() পদ্ধতিতে কল করুন, সংশ্লিষ্ট স্কোর ফ্র্যাগমেন্ট প্রসঙ্গে এবং viewModelFactory পাস করুন। এটি viewModelFactory ক্লাসে সংজ্ঞায়িত ফ্যাক্টরি পদ্ধতি ব্যবহার করে ScoreViewModel অবজেক্ট তৈরি করবে .
viewModel = ViewModelProviders.of(this, viewModelFactory)
       .get(ScoreViewModel::class.java)
  1. onCreateView() পদ্ধতিতে, viewModel আরম্ভ করার পরে, ScoreViewModel এ সংজ্ঞায়িত চূড়ান্ত স্কোরে scoreText ভিউ-এর পাঠ্য সেট করুন।
binding.scoreText.text = viewModel.score.toString()
  1. আপনার অ্যাপটি চালান এবং গেমটি খেলুন। কিছু বা সমস্ত শব্দের মধ্য দিয়ে সাইকেল করুন এবং গেম শেষ করুন আলতো চাপুন। লক্ষ্য করুন যে স্কোর খণ্ডটি এখন চূড়ান্ত স্কোর প্রদর্শন করে।

  1. ঐচ্ছিক: ScoreViewModel এ ফিল্টার করে Logcat-এ ScoreViewModel লগগুলি পরীক্ষা করুন। স্কোর মান প্রদর্শন করা উচিত।
2019-02-07 10:50:18.328 com.example.android.guesstheword I/ScoreViewModel: Final score is 15

এই টাস্কে, আপনি ViewModel ব্যবহার করতে ScoreFragment প্রয়োগ করেছেন। আপনি ViewModelFactory ইন্টারফেস ব্যবহার করে একটি ViewModel জন্য একটি প্যারামিটারাইজড কনস্ট্রাক্টর তৈরি করতে শিখেছেন।

অভিনন্দন! আপনি Android আর্কিটেকচার উপাদানগুলির একটি, ViewModel ব্যবহার করতে আপনার অ্যাপের আর্কিটেকচার পরিবর্তন করেছেন। আপনি অ্যাপের লাইফসাইকেল সমস্যাটি সমাধান করেছেন এবং এখন গেমের ডেটা কনফিগারেশন পরিবর্তনগুলি থেকে বেঁচে থাকে। আপনি ViewModelFactory ইন্টারফেস ব্যবহার করে একটি ViewModel তৈরি করার জন্য একটি প্যারামিটারাইজড কনস্ট্রাক্টর তৈরি করতে শিখেছেন।

অ্যান্ড্রয়েড স্টুডিও প্রকল্প: GuessTheWord

  • অ্যান্ড্রয়েড অ্যাপ আর্কিটেকচার নির্দেশিকা বিভিন্ন দায়বদ্ধ ক্লাসগুলিকে আলাদা করার সুপারিশ করে৷
  • একটি UI কন্ট্রোলার হল UI-ভিত্তিক ক্লাস যেমন Activity বা Fragment । UI কন্ট্রোলারগুলিতে শুধুমাত্র যুক্তি থাকা উচিত যা UI এবং অপারেটিং সিস্টেমের মিথস্ক্রিয়া পরিচালনা করে; তাদের UI-তে প্রদর্শিত ডেটা থাকা উচিত নয়। একটি ViewModel এ তথ্য রাখুন।
  • ViewModel ক্লাস UI- সম্পর্কিত ডেটা সঞ্চয় করে এবং পরিচালনা করে। ViewModel ক্লাস ডেটাকে স্ক্রিন ঘূর্ণনের মতো কনফিগারেশন পরিবর্তনগুলিকে বাঁচতে দেয়।
  • ViewModel প্রস্তাবিত Android আর্কিটেকচার উপাদানগুলির মধ্যে একটি।
  • ViewModelProvider.Factory হল একটি ইন্টারফেস যা আপনি একটি ViewModel অবজেক্ট তৈরি করতে ব্যবহার করতে পারেন।

নীচের টেবিলটি UI কন্ট্রোলারের সাথে ViewModel দৃষ্টান্তের তুলনা করে যা তাদের জন্য ডেটা রাখে:

UI কন্ট্রোলার

মডেল দেখুন

একটি UI কন্ট্রোলারের একটি উদাহরণ হল ScoreFragment যা আপনি এই কোডল্যাবে তৈরি করেছেন।

একটি ViewModel এর একটি উদাহরণ হল ScoreViewModel যা আপনি এই কোডল্যাবে তৈরি করেছেন।

UI-তে দেখানোর জন্য কোনো ডেটা নেই।

UI কন্ট্রোলার UI-তে যে ডেটা প্রদর্শন করে তা ধারণ করে।

ডেটা প্রদর্শনের জন্য কোড এবং ব্যবহারকারী-ইভেন্ট কোড যেমন ক্লিক শ্রোতাদের রয়েছে।

ডেটা প্রক্রিয়াকরণের জন্য কোড রয়েছে।

প্রতিটি কনফিগারেশন পরিবর্তনের সময় ধ্বংস এবং পুনরায় তৈরি করা হয়।

শুধুমাত্র তখনই ধ্বংস করা হয় যখন সংশ্লিষ্ট UI কন্ট্রোলার স্থায়ীভাবে চলে যায়—একটি ক্রিয়াকলাপের জন্য, যখন কার্যকলাপ শেষ হয়, অথবা একটি খণ্ডের জন্য, যখন খণ্ডটি বিচ্ছিন্ন হয়৷

ভিউ রয়েছে।

ক্রিয়াকলাপ, টুকরো বা দৃশ্যের রেফারেন্স কখনই থাকা উচিত নয়, কারণ সেগুলি কনফিগারেশন পরিবর্তনগুলি থেকে বাঁচে না, তবে ViewModel তা করে।

সংশ্লিষ্ট ViewModel এর একটি রেফারেন্স রয়েছে।

সংশ্লিষ্ট UI কন্ট্রোলারের কোনো রেফারেন্স নেই।

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

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

অন্যান্য:

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

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

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

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

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

প্রশ্ন 1

ডিভাইস-কনফিগারেশন পরিবর্তনের সময় ডেটা হারানো এড়াতে, আপনার কোন ক্লাসে অ্যাপ ডেটা সংরক্ষণ করা উচিত?

  • ViewModel
  • LiveData
  • Fragment
  • Activity

প্রশ্ন 2

একটি ViewModel কখনই টুকরো, কার্যকলাপ বা দৃশ্যের কোনো উল্লেখ থাকা উচিত নয়। সত্য না মিথ্যা?

  • সত্য
  • মিথ্যা

প্রশ্ন 3

কখন একটি ViewModel ধ্বংস হয়?

  • ডিভাইস-ওরিয়েন্টেশন পরিবর্তনের সময় সংশ্লিষ্ট UI কন্ট্রোলারটি ধ্বংস হয়ে গেলে পুনরায় তৈরি করা হয়।
  • একটি অভিযোজন পরিবর্তন.
  • যখন সংশ্লিষ্ট UI কন্ট্রোলার সমাপ্ত হয় (যদি এটি একটি কার্যকলাপ হয়) বা বিচ্ছিন্ন (যদি এটি একটি খণ্ড হয়)।
  • যখন ব্যবহারকারী ব্যাক বোতাম টিপুন।

প্রশ্ন 4

ViewModelFactory ইন্টারফেস কি জন্য?

  • একটি ViewModel অবজেক্ট ইনস্ট্যান্টিয়েটিং।
  • অভিযোজন পরিবর্তনের সময় ডেটা ধরে রাখা।
  • স্ক্রিনে প্রদর্শিত ডেটা রিফ্রেশ করা হচ্ছে।
  • অ্যাপের ডেটা পরিবর্তন হলে বিজ্ঞপ্তি পাওয়া।

পরবর্তী পাঠ শুরু করুন: 5.2: LiveData এবং LiveData পর্যবেক্ষক

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