এই কোডল্যাবটি অ্যান্ড্রয়েড কোটলিন ফান্ডামেন্টাল কোর্সের অংশ। আপনি যদি ক্রমানুসারে কোডল্যাবগুলির মাধ্যমে কাজ করেন তবে আপনি এই কোর্সের সর্বাধিক মূল্য পাবেন৷ সমস্ত কোর্স কোডল্যাব অ্যান্ড্রয়েড কোটলিন ফান্ডামেন্টাল কোডল্যাব ল্যান্ডিং পৃষ্ঠায় তালিকাভুক্ত করা হয়েছে।
ভূমিকা
পূর্ববর্তী কোডল্যাবে, আপনি ডিভাইস-কনফিগারেশন পরিবর্তনগুলি থেকে বাঁচতে অ্যাপের ডেটাকে অনুমতি দিতে GuessTheWord অ্যাপে একটি ViewModel
ব্যবহার করেছেন। এই কোডল্যাবে, আপনি ViewModel
ক্লাসের ডেটার সাথে LiveData
কীভাবে সংহত করতে হয় তা শিখবেন। LiveData
, যা অ্যান্ড্রয়েড আর্কিটেকচার উপাদানগুলির মধ্যে একটি, আপনাকে এমন ডেটা অবজেক্ট তৈরি করতে দেয় যা অন্তর্নিহিত ডাটাবেস পরিবর্তনের সময় ভিউকে অবহিত করে।
LiveData
ক্লাস ব্যবহার করার জন্য, আপনি "পর্যবেক্ষক" (উদাহরণস্বরূপ, কার্যকলাপ বা টুকরা) সেট আপ করেন যা অ্যাপের ডেটাতে পরিবর্তনগুলি পর্যবেক্ষণ করে। LiveData
হল লাইফসাইকেল-সচেতন, তাই এটি শুধুমাত্র অ্যাপ-কম্পোনেন্ট পর্যবেক্ষকদের আপডেট করে যারা সক্রিয় জীবনচক্র অবস্থায় আছে।
আপনি ইতিমধ্যে কি জানা উচিত
- কোটলিনে কীভাবে বেসিক অ্যান্ড্রয়েড অ্যাপ তৈরি করবেন।
- আপনার অ্যাপের গন্তব্যের মধ্যে কীভাবে নেভিগেট করবেন।
- কার্যকলাপ এবং খণ্ড জীবনচক্র।
- আপনার অ্যাপে
ViewModel
অবজেক্টগুলি কীভাবে ব্যবহার করবেন। - কিভাবে
ViewModelProvider.Factory
ইন্টারফেস ব্যবহার করেViewModel
অবজেক্ট তৈরি করবেন।
আপনি কি শিখবেন
- কি
LiveData
বস্তু দরকারী করে তোলে. -
ViewModel
সংরক্ষিত ডেটাতে কীভাবেLiveData
যুক্ত করবেন। - কখন এবং কিভাবে
MutableLiveData
ব্যবহার করবেন। -
LiveData.
- একটি ব্যাকিং সম্পত্তি ব্যবহার করে কিভাবে
LiveData
এনক্যাপসুলেট করবেন। - কিভাবে একটি UI কন্ট্রোলার এবং এর সংশ্লিষ্ট
ViewModel
এর মধ্যে যোগাযোগ করতে হয়।
আপনি কি করবেন
- GuessTheWord অ্যাপে শব্দ এবং স্কোরের জন্য
LiveData
ব্যবহার করুন। - শব্দ বা স্কোর পরিবর্তিত হলে লক্ষ্য করে এমন পর্যবেক্ষকদের যোগ করুন।
- পরিবর্তিত মানগুলি প্রদর্শন করে এমন পাঠ্য দৃশ্যগুলি আপডেট করুন।
- একটি গেম-সমাপ্ত ইভেন্ট যোগ করতে
LiveData
পর্যবেক্ষক প্যাটার্ন ব্যবহার করুন। - আবার প্লে বোতামটি প্রয়োগ করুন।
পাঠ 5 কোডল্যাবগুলিতে, আপনি স্টার্টার কোড দিয়ে শুরু করে GuessTheWord অ্যাপ তৈরি করেন। GuessTheWord হল একটি দুই-প্লেয়ার চ্যারেড -স্টাইলের খেলা, যেখানে খেলোয়াড়রা সম্ভাব্য সর্বোচ্চ স্কোর অর্জন করতে সহযোগিতা করে।
প্রথম প্লেয়ার অ্যাপে থাকা শব্দগুলি দেখে এবং পালাক্রমে প্রতিটি কাজ করে, নিশ্চিত করে যে শব্দটি দ্বিতীয় প্লেয়ারকে না দেখায়৷ দ্বিতীয় খেলোয়াড় শব্দটি অনুমান করার চেষ্টা করে।
গেমটি খেলতে, প্রথম প্লেয়ার ডিভাইসে অ্যাপটি খোলে এবং একটি শব্দ দেখতে পায়, উদাহরণস্বরূপ "গিটার", যেমনটি নীচের স্ক্রিনশটে দেখানো হয়েছে৷
প্রথম খেলোয়াড় শব্দটি কার্যকর করে, সতর্কতা অবলম্বন করে যে শব্দটি নিজেই না বলে।
- যখন দ্বিতীয় প্লেয়ার সঠিকভাবে শব্দটি অনুমান করে, প্রথম প্লেয়ার Got It বোতাম টিপে, যা এক দ্বারা গণনা বৃদ্ধি করে এবং পরবর্তী শব্দটি দেখায়।
- যদি দ্বিতীয় প্লেয়ার শব্দটি অনুমান করতে না পারে, প্রথম খেলোয়াড় স্কিপ বোতাম টিপে, যা গণনা এক দ্বারা হ্রাস করে এবং পরবর্তী শব্দে চলে যায়।
- গেমটি শেষ করতে, এন্ড গেম বোতাম টিপুন। (এই কার্যকারিতা সিরিজের প্রথম কোডল্যাবের জন্য স্টার্টার কোডে নেই।)
এই কোডল্যাবে, আপনি গেমটি শেষ করার জন্য একটি ইভেন্ট যোগ করে GuessTheWord অ্যাপটিকে উন্নত করেন যখন ব্যবহারকারী অ্যাপের সমস্ত শব্দের মাধ্যমে চক্রাকারে যান। এছাড়াও আপনি স্কোর ফ্র্যাগমেন্টে একটি প্লে এগেইন বোতাম যোগ করুন, যাতে ব্যবহারকারী আবার গেমটি খেলতে পারেন।
শিরোনাম পর্দা | খেলা পর্দা | স্কোর স্ক্রীন |
এই কাজটিতে, আপনি এই কোডল্যাবের জন্য আপনার স্টার্টার কোডটি সনাক্ত করুন এবং চালান। আপনি আপনার স্টার্টার কোড হিসাবে পূর্ববর্তী কোডল্যাবে তৈরি করা GuessTheWord অ্যাপটি ব্যবহার করতে পারেন, অথবা আপনি একটি স্টার্টার অ্যাপ ডাউনলোড করতে পারেন।
- (ঐচ্ছিক) আপনি যদি আগের কোডল্যাব থেকে আপনার কোড ব্যবহার না করে থাকেন, তাহলে এই কোডল্যাবের জন্য স্টার্টার কোডটি ডাউনলোড করুন । কোডটি আনজিপ করুন এবং অ্যান্ড্রয়েড স্টুডিওতে প্রকল্পটি খুলুন।
- অ্যাপটি চালান এবং গেমটি খেলুন।
- লক্ষ্য করুন যে Skip বোতামটি পরবর্তী শব্দটি প্রদর্শন করে এবং একটি দ্বারা স্কোর হ্রাস করে এবং Got It বোতামটি পরবর্তী শব্দটি দেখায় এবং একটি দ্বারা স্কোর বৃদ্ধি করে। এন্ড গেম বোতামটি গেমটি শেষ করে।
LiveData
হল একটি পর্যবেক্ষণযোগ্য ডেটা ধারক শ্রেণী যা জীবনচক্র-সচেতন। উদাহরণস্বরূপ, আপনি GuessTheWord অ্যাপে বর্তমান স্কোরের চারপাশে একটি LiveData
মোড়ানো করতে পারেন। এই কোডল্যাবে, আপনি LiveData
এর বিভিন্ন বৈশিষ্ট্য সম্পর্কে জানতে পারবেন:
-
LiveData
হল পর্যবেক্ষণযোগ্য, যার মানে হল যখনLiveData
অবজেক্ট দ্বারা ধারণকৃত ডেটা পরিবর্তিত হয় তখন একজন পর্যবেক্ষককে অবহিত করা হয়। -
LiveData
ডেটা ধারণ করে;LiveData
হল একটি মোড়ক যা যেকোনো ডেটার সাথে ব্যবহার করা যেতে পারে -
LiveData
হল লাইফসাইকেল-সচেতন, মানে এটি শুধুমাত্র এমন পর্যবেক্ষকদের আপডেট করে যারা একটি সক্রিয় জীবনচক্র অবস্থায় আছে যেমনSTARTED
করা বাRESUMED
করা হয়েছে।
এই টাস্কে, আপনি কিভাবে GameViewModel-এর বর্তমান স্কোর এবং বর্তমান শব্দ ডেটাকে GameViewModel
এ রূপান্তর করে LiveData
অবজেক্টে যেকোনও ডেটা টাইপ মোড়ানো LiveData
। পরবর্তী একটি টাস্কে, আপনি এই LiveData
অবজেক্টগুলিতে একজন পর্যবেক্ষক যোগ করুন এবং কিভাবে LiveData
পর্যবেক্ষণ করতে হয় তা শিখুন।
ধাপ 1: LiveData ব্যবহার করতে স্কোর এবং শব্দ পরিবর্তন করুন
-
screens/game
প্যাকেজের অধীনে,GameViewModel
ফাইলটি খুলুন। - পরিবর্তনশীল
score
এবংword
ধরন পরিবর্তন করেMutableLiveData
।
MutableLiveData
হল একটিLiveData
যার মান পরিবর্তন করা যায়।MutableLiveData
হল একটি জেনেরিক ক্লাস, তাই আপনাকে এটিতে থাকা ডেটার ধরন নির্দিষ্ট করতে হবে।
// The current word
val word = MutableLiveData<String>()
// The current score
val score = MutableLiveData<Int>()
-
GameViewModel
এ,init
ব্লকের ভিতরে,score
এবংword
শুরু করুন। একটিLiveData
ভেরিয়েবলের মান পরিবর্তন করতে, আপনি ভেরিয়েবলেsetValue()
পদ্ধতি ব্যবহার করেন। কোটলিনে, আপনিvalue
সম্পত্তি ব্যবহার করেsetValue()
কল করতে পারেন।
init {
word.value = ""
score.value = 0
...
}
ধাপ 2: LiveData অবজেক্ট রেফারেন্স আপডেট করুন
score
এবং word
ভেরিয়েবল এখন LiveData
ধরনের। এই ধাপে, আপনি value
সম্পত্তি ব্যবহার করে এই ভেরিয়েবলের রেফারেন্স পরিবর্তন করুন।
-
GameViewModel
এ,onSkip()
পদ্ধতিতে,score
পরিবর্তন করেscore.value
।score
সম্ভবতnull
হওয়ার বিষয়ে ত্রুটিটি লক্ষ্য করুন। আপনি পরবর্তী এই ত্রুটি ঠিক করুন. - ত্রুটিটি সমাধান করতে,
onSkip()
এscore.value
এ একটিnull
চেক যোগ করুন। তারপরscore
minus()
ফাংশন কল করুন, যাnull
-safety সহ বিয়োগ সম্পাদন করে।
fun onSkip() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.minus(1)
}
nextWord()
}
-
onCorrect()
পদ্ধতিটি আপডেট করুন:score
ভেরিয়েবলে একটিnull
চেক যুক্ত করুন এবংplus()
ফাংশনটি ব্যবহার করুন।
fun onCorrect() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.plus(1)
}
nextWord()
}
-
GameViewModel
এ,nextWord()
পদ্ধতির ভিতরে,word
রেফারেন্সword
পরিবর্তন করুন.
value
private fun nextWord() {
if (!wordList.isEmpty()) {
//Select and remove a word from the list
word.value = wordList.removeAt(0)
}
}
-
GameFragment
এ,updateWordText()
পদ্ধতির ভিতরে,viewModel
.word
থেকেviewModel
এ রেফারেন্স পরিবর্তন করুন.
word
.
value.
/** Methods for updating the UI **/
private fun updateWordText() {
binding.wordText.text = viewModel.word.value
}
-
GameFragment
এ,updateScoreText()
পদ্ধতির ভিতরে,viewModel
.score
এর রেফারেন্স পরিবর্তন করেviewModel
করুন.
score
.
value.
private fun updateScoreText() {
binding.scoreText.text = viewModel.score.value.toString()
}
-
GameFragment
এ,gameFinished()
পদ্ধতির ভিতরে,viewModel
.score
এ রেফারেন্স পরিবর্তন করেviewModel
করুন.
score
.
value
প্রয়োজনীয়null
-সেফটি চেক যোগ করুন।
private fun gameFinished() {
Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
val action = GameFragmentDirections.actionGameToScore()
action.score = viewModel.score.value?:0
NavHostFragment.findNavController(this).navigate(action)
}
- আপনার কোডে কোন ত্রুটি আছে তা নিশ্চিত করুন। কম্পাইল এবং আপনার অ্যাপ্লিকেশন চালান. অ্যাপটির কার্যকারিতা আগের মতোই হওয়া উচিত।
এই টাস্কটি আগের টাস্কের সাথে ঘনিষ্ঠভাবে সম্পর্কিত, যেখানে আপনি স্কোর এবং শব্দ ডেটাকে LiveData
অবজেক্টে রূপান্তর করেছেন। এই টাস্কে, আপনি সেই LiveData
অবজেক্টের সাথে Observer
অবজেক্ট সংযুক্ত করুন।
-
GameFragment,
onCreateView()
পদ্ধতির ভিতরে, বর্তমান স্কোর,viewModel.score
এর জন্যLiveData
অবজেক্টের সাথে একটিObserver
অবজেক্ট সংযুক্ত করুন।observe()
পদ্ধতিটি ব্যবহার করুন এবংviewModel
এর আরম্ভ করার পরে কোডটি রাখুন। কোডটি সরল করতে একটি ল্যাম্বডা এক্সপ্রেশন ব্যবহার করুন। (একটি ল্যাম্বডা এক্সপ্রেশন একটি বেনামী ফাংশন যা ঘোষণা করা হয় না, তবে একটি অভিব্যক্তি হিসাবে অবিলম্বে পাস করা হয়।)
viewModel.score.observe(this, Observer { newScore ->
})
Observer
রেফারেন্সটি সমাধান করুন। এটি করার জন্য, Observer
এ ক্লিক করুন, Alt+Enter
( Mac-এ Option+Enter
), এবং androidx.lifecycle.Observer
আমদানি করুন।
- আপনি যে পর্যবেক্ষকটি এইমাত্র তৈরি করেছেন সেটি একটি ইভেন্ট গ্রহণ করে যখন পর্যবেক্ষণ করা
LiveData
অবজেক্ট দ্বারা ধারণকৃত ডেটা পরিবর্তিত হয়। পর্যবেক্ষকের ভিতরে, নতুন স্কোর সহTextView
স্কোর আপডেট করুন।
/** Setting up LiveData observation relationship **/
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
- বর্তমান শব্দ
LiveData
অবজেক্টের সাথে একটিObserver
বস্তু সংযুক্ত করুন। আপনি বর্তমান স্কোরের সাথে একটিObserver
বস্তু সংযুক্ত করেছেন একইভাবে এটি করুন।
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
binding.wordText.text = newWord
})
যখন score
বা word
মান পরিবর্তিত হয়, তখন স্ক্রিনে প্রদর্শিত score
বা word
এখন স্বয়ংক্রিয়ভাবে আপডেট হয়।
-
GameFragment
এ,updateWordText()
এবংupdateScoreText()
) পদ্ধতি এবং সেগুলির সমস্ত রেফারেন্স মুছে দিন। আপনার আর এগুলোর প্রয়োজন নেই, কারণ টেক্সট ভিউLiveData
পর্যবেক্ষক পদ্ধতি দ্বারা আপডেট করা হয়। - আপনার অ্যাপ চালান। আপনার গেম অ্যাপটি ঠিক আগের মতোই কাজ করা উচিত, কিন্তু এখন এটি
LiveData
এবংLiveData
পর্যবেক্ষক ব্যবহার করে।
এনক্যাপসুলেশন হল একটি বস্তুর কিছু ক্ষেত্রে সরাসরি অ্যাক্সেস সীমাবদ্ধ করার একটি উপায়। আপনি যখন একটি বস্তুকে এনক্যাপসুলেট করেন, তখন আপনি সর্বজনীন পদ্ধতির একটি সেট প্রকাশ করেন যা ব্যক্তিগত অভ্যন্তরীণ ক্ষেত্রগুলিকে সংশোধন করে। এনক্যাপসুলেশন ব্যবহার করে, আপনি নিয়ন্ত্রণ করেন কিভাবে অন্যান্য ক্লাস এই অভ্যন্তরীণ ক্ষেত্রগুলিকে ম্যানিপুলেট করে।
আপনার বর্তমান কোডে, যেকোনো বাহ্যিক শ্রেণী value
বৈশিষ্ট্য ব্যবহার করে score
এবং word
ভেরিয়েবল পরিবর্তন করতে পারে, উদাহরণস্বরূপ viewModel.score.value
ব্যবহার করে। আপনি এই কোডল্যাবে যে অ্যাপটি ডেভেলপ করছেন তাতে কিছু যায় আসে না, কিন্তু একটি প্রোডাকশন অ্যাপে, আপনি ViewModel
অবজেক্টের ডেটার উপর নিয়ন্ত্রণ চান।
শুধুমাত্র ViewModel
আপনার অ্যাপের ডেটা সম্পাদনা করবে। কিন্তু UI কন্ট্রোলারদের ডেটা পড়তে হবে, তাই ডেটা ক্ষেত্রগুলি সম্পূর্ণ ব্যক্তিগত হতে পারে না। আপনার অ্যাপের ডেটা এনক্যাপসুলেট করতে, আপনি MutableLiveData
এবং LiveData
অবজেক্ট উভয়ই ব্যবহার করেন।
MutableLiveData
বনাম LiveData
:
- একটি
MutableLiveData
অবজেক্টের ডেটা পরিবর্তন করা যেতে পারে, যেমন নামটি বোঝায়।ViewModel
এর ভিতরে, ডেটা সম্পাদনাযোগ্য হওয়া উচিত, তাই এটিMutableLiveData
ব্যবহার করে। - একটি
LiveData
অবজেক্টের ডেটা পড়া যায়, কিন্তু পরিবর্তন করা যায় না।ViewModel
এর বাইরে থেকে, ডেটা পাঠযোগ্য হওয়া উচিত, কিন্তু সম্পাদনাযোগ্য নয়, তাই ডেটাLiveData
হিসাবে প্রকাশ করা উচিত।
এই কৌশলটি চালানোর জন্য, আপনি একটি Kotlin ব্যাকিং সম্পত্তি ব্যবহার করুন। একটি ব্যাকিং প্রপার্টি আপনাকে সঠিক বস্তু ব্যতীত অন্য গেটার থেকে কিছু ফেরত দিতে দেয়। এই কাজটিতে, আপনি GuessTheWord অ্যাপে score
এবং word
বস্তুর জন্য একটি ব্যাকিং প্রপার্টি প্রয়োগ করেন।
স্কোর এবং শব্দে একটি ব্যাকিং সম্পত্তি যোগ করুন
-
GameViewModel
এ, বর্তমানscore
অবজেক্টটিকেprivate
করুন। - ব্যাকিং বৈশিষ্ট্যে ব্যবহৃত নামকরণের নিয়ম অনুসরণ করতে,
score
_score
এ পরিবর্তন করুন।_score
সম্পত্তিটি এখন গেম স্কোরের পরিবর্তনযোগ্য সংস্করণ, যা অভ্যন্তরীণভাবে ব্যবহার করা হবে। -
LiveData
প্রকারের একটি সর্বজনীন সংস্করণ তৈরি করুন, যাকে বলা হয়score
।
// The current score
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
- আপনি একটি আরম্ভ ত্রুটি দেখতে. এই ত্রুটিটি ঘটে কারণ
GameFragment
ভিতরে,score
একটিLiveData
রেফারেন্স, এবংscore
আর এটির সেটার অ্যাক্সেস করতে পারে না। কোটলিনে গেটার এবং সেটার্স সম্পর্কে আরও জানতে, গেটার এবং সেটার্স দেখুন।
ত্রুটিটি সমাধান করতে,GameViewModel
এscore
অবজেক্টের জন্যget()
পদ্ধতিটি ওভাররাইড করুন এবং ব্যাকিং প্রপার্টি,_score
।
val score: LiveData<Int>
get() = _score
-
GameViewModel
এ,score
রেফারেন্সগুলি এর অভ্যন্তরীণ পরিবর্তনযোগ্য সংস্করণে পরিবর্তন করুন,_score
।
init {
...
_score.value = 0
...
}
...
fun onSkip() {
if (!wordList.isEmpty()) {
_score.value = (score.value)?.minus(1)
}
...
}
fun onCorrect() {
if (!wordList.isEmpty()) {
_score.value = (score.value)?.plus(1)
}
...
}
-
word
অবজেক্টের নাম পরিবর্তন করে_word
করুন এবং এর জন্য একটি ব্যাকিং প্রপার্টি যোগ করুন, যেমন আপনিscore
অবজেক্টের জন্য করেছিলেন।
// The current word
private val _word = MutableLiveData<String>()
val word: LiveData<String>
get() = _word
...
init {
_word.value = ""
...
}
...
private fun nextWord() {
if (!wordList.isEmpty()) {
//Select and remove a word from the list
_word.value = wordList.removeAt(0)
}
}
দুর্দান্ত কাজ, আপনি LiveData
অবজেক্টের word
এবং score
এনক্যাপসুলেট করেছেন।
ব্যবহারকারী যখন এন্ড গেম বোতামে ট্যাপ করে তখন আপনার বর্তমান অ্যাপটি স্কোর স্ক্রিনে নেভিগেট করে। খেলোয়াড়রা সমস্ত শব্দের মাধ্যমে সাইকেল চালালে আপনি অ্যাপটিকে স্কোর স্ক্রিনে নেভিগেট করতে চান। খেলোয়াড়রা শেষ শব্দটি দিয়ে শেষ করার পরে, আপনি গেমটি স্বয়ংক্রিয়ভাবে শেষ করতে চান যাতে ব্যবহারকারীকে বোতামটি আলতো চাপতে না হয়।
এই কার্যকারিতা বাস্তবায়নের জন্য, আপনার একটি ইভেন্ট ট্রিগার করা এবং ViewModel
থেকে খণ্ডের সাথে যোগাযোগ করা দরকার যখন সমস্ত শব্দ দেখানো হয়েছে৷ এটি করার জন্য, আপনি একটি গেম-সমাপ্ত ইভেন্ট মডেল করতে LiveData
পর্যবেক্ষক প্যাটার্ন ব্যবহার করেন।
পর্যবেক্ষক প্যাটার্ন
পর্যবেক্ষক প্যাটার্ন হল একটি সফটওয়্যার ডিজাইন প্যাটার্ন। এটি বস্তুর মধ্যে যোগাযোগ নির্দিষ্ট করে: একটি পর্যবেক্ষণযোগ্য (পর্যবেক্ষণের "বিষয়") এবং পর্যবেক্ষক । একটি পর্যবেক্ষণযোগ্য একটি বস্তু যা তার অবস্থার পরিবর্তন সম্পর্কে পর্যবেক্ষকদের অবহিত করে।
এই অ্যাপে LiveData
এর ক্ষেত্রে, পর্যবেক্ষণযোগ্য (বিষয়) হল LiveData
অবজেক্ট, এবং পর্যবেক্ষক হল UI কন্ট্রোলারের পদ্ধতি, যেমন টুকরা। যখনই LiveData
এর ভিতরে মোড়ানো ডেটা পরিবর্তিত হয় তখনই একটি রাজ্যের পরিবর্তন ঘটে। ViewModel
থেকে টুকরোতে যোগাযোগ করার জন্য LiveData
ক্লাসগুলি অত্যন্ত গুরুত্বপূর্ণ৷
ধাপ 1: একটি গেম-সমাপ্ত ইভেন্ট সনাক্ত করতে LiveData ব্যবহার করুন
এই টাস্কে, আপনি একটি গেম-সমাপ্ত ইভেন্ট মডেল করতে LiveData
পর্যবেক্ষক প্যাটার্ন ব্যবহার করেন।
-
GameViewModel
এ, _eventGameFinish নামে একটিBoolean
MutableLiveData
_eventGameFinish
তৈরি করুন। এই বস্তুটি গেম-সমাপ্ত ইভেন্টটি ধরে রাখবে। -
_eventGameFinish
অবজেক্ট আরম্ভ করার পরে,eventGameFinish
নামে একটি ব্যাকিং প্রপার্টি তৈরি করুন এবং আরম্ভ করুন।
// Event which triggers the end of the game
private val _eventGameFinish = MutableLiveData<Boolean>()
val eventGameFinish: LiveData<Boolean>
get() = _eventGameFinish
-
GameViewModel
এ, একটিonGameFinish()
পদ্ধতি যোগ করুন। পদ্ধতিতে, গেম-সমাপ্ত ইভেন্ট,eventGameFinish
,true
সেট করুন।
/** Method for the game completed event **/
fun onGameFinish() {
_eventGameFinish.value = true
}
-
GameViewModel
এ,nextWord()
পদ্ধতির ভিতরে, শব্দ তালিকা খালি থাকলে গেমটি শেষ করুন।
private fun nextWord() {
if (wordList.isEmpty()) {
onGameFinish()
} else {
//Select and remove a _word from the list
_word.value = wordList.removeAt(0)
}
}
-
GameFragment
এ, onCreateViewonCreateView()
-এর ভিতরে, viewModel শুরু করার পর,viewModel
এ একজন পর্যবেক্ষক সংযুক্তeventGameFinish
।observe()
পদ্ধতি ব্যবহার করুন। ল্যাম্বডা ফাংশনের ভিতরে,gameFinished()
পদ্ধতিতে কল করুন।
// Observer for the Game finished event
viewModel.eventGameFinish.observe(this, Observer<Boolean> { hasFinished ->
if (hasFinished) gameFinished()
})
- আপনার অ্যাপ চালান, গেম খেলুন এবং সমস্ত শব্দের মধ্য দিয়ে যান। আপনি End Game এ ট্যাপ না করা পর্যন্ত গেমের অংশে থাকার পরিবর্তে অ্যাপটি স্বয়ংক্রিয়ভাবে স্কোর স্ক্রিনে নেভিগেট করে।
শব্দ তালিকা খালি হওয়ার পরে,eventGameFinish
সেট করা হয়, গেমের খণ্ডে সংশ্লিষ্ট পর্যবেক্ষক পদ্ধতিকে কল করা হয় এবং অ্যাপটি স্ক্রিন ফ্র্যাগমেন্টে নেভিগেট করে। - আপনার যোগ করা কোড একটি জীবনচক্র সমস্যা চালু করেছে। সমস্যাটি বুঝতে,
GameFragment
ক্লাসে,gameFinished()
পদ্ধতিতে নেভিগেশন কোডটি মন্তব্য করুন। পদ্ধতিতেToast
বার্তা রাখতে ভুলবেন না।
private fun gameFinished() {
Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
// val action = GameFragmentDirections.actionGameToScore()
// action.score = viewModel.score.value?:0
// NavHostFragment.findNavController(this).navigate(action)
}
- আপনার অ্যাপ চালান, গেম খেলুন এবং সমস্ত শব্দের মধ্য দিয়ে যান। একটি টোস্ট বার্তা যা বলে "গেম সবে শেষ হয়েছে" গেম স্ক্রিনের নীচে সংক্ষেপে প্রদর্শিত হবে, যা প্রত্যাশিত আচরণ।
এখন ডিভাইস বা এমুলেটর ঘোরান। টোস্ট আবার প্রদর্শন! ডিভাইসটি আরও কয়েকবার ঘোরান, এবং আপনি সম্ভবত প্রতিবার টোস্ট দেখতে পাবেন। এটি একটি বাগ, কারণ টোস্ট শুধুমাত্র একবার প্রদর্শন করা উচিত, যখন খেলা শেষ হয়। প্রতিবার খণ্ডটি পুনরায় তৈরি করার সময় টোস্টটি প্রদর্শন করা উচিত নয়। আপনি পরবর্তী টাস্কে এই সমস্যাটি সমাধান করুন।
ধাপ 2: গেম-সমাপ্ত ইভেন্ট রিসেট করুন
সাধারণত, LiveData
শুধুমাত্র ডেটা পরিবর্তিত হলেই পর্যবেক্ষকদের কাছে আপডেট প্রদান করে। এই আচরণের একটি ব্যতিক্রম হল যখন পর্যবেক্ষক একটি নিষ্ক্রিয় থেকে একটি সক্রিয় অবস্থায় পরিবর্তিত হয় তখন পর্যবেক্ষকরাও আপডেট পান।
এই কারণেই আপনার অ্যাপে গেম-সমাপ্ত টোস্ট বারবার ট্রিগার হয়। যখন স্ক্রীন ঘূর্ণনের পরে গেমের খণ্ডটি পুনরায় তৈরি করা হয়, তখন এটি একটি নিষ্ক্রিয় থেকে একটি সক্রিয় অবস্থায় চলে যায়। খণ্ডের পর্যবেক্ষক বিদ্যমান ViewModel
সাথে পুনরায় সংযুক্ত হয় এবং বর্তমান ডেটা গ্রহণ করে। gameFinished()
পদ্ধতিটি পুনরায় ট্রিগার করা হয় এবং টোস্ট প্রদর্শন করা হয়।
এই টাস্কে, আপনি এই সমস্যাটি ঠিক করুন এবং GameViewModel
এ eventGameFinish
পতাকা রিসেট করে শুধুমাত্র একবার টোস্ট প্রদর্শন করুন।
-
GameViewModel
এ, গেম সমাপ্ত ইভেন্ট,_eventGameFinish
রিসেট করতে একটিonGameFinishComplete()
পদ্ধতি যোগ করুন।
/** Method for the game completed event **/
fun onGameFinishComplete() {
_eventGameFinish.value = false
}
-
GameFragment
এ,gameFinished()
এর শেষে,viewModel
অবজেক্টেonGameFinishComplete()
কল করুন। (gameFinished()
এ নেভিগেশন কোড ছেড়ে দিন এখনের জন্য মন্তব্য করা হয়েছে।)
private fun gameFinished() {
...
viewModel.onGameFinishComplete()
}
- অ্যাপটি চালান এবং গেমটি খেলুন। সমস্ত শব্দের মধ্য দিয়ে যান, তারপর ডিভাইসের পর্দার অভিযোজন পরিবর্তন করুন। টোস্ট শুধুমাত্র একবার প্রদর্শিত হয়.
-
GameFragment
এ,gameFinished()
পদ্ধতির ভিতরে, নেভিগেশন কোডটি আনকমেন্ট করুন।
অ্যান্ড্রয়েড স্টুডিওতে মন্তব্য করার জন্য, মন্তব্য করা লাইনগুলি নির্বাচন করুন এবংControl+/
( একটি ম্যাকেCommand+/
) টিপুন।
private fun gameFinished() {
Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
val action = GameFragmentDirections.actionGameToScore()
action.score = viewModel.score.value?:0
findNavController(this).navigate(action)
viewModel.onGameFinishComplete()
}
Android Studio দ্বারা অনুরোধ করা হলে, androidx.navigation.fragment.NavHostFragment.findNavController
আমদানি করুন।
- অ্যাপটি চালান এবং গেমটি খেলুন। আপনি সমস্ত শব্দের মধ্য দিয়ে যাওয়ার পরে অ্যাপটি চূড়ান্ত স্কোর স্ক্রিনে স্বয়ংক্রিয়ভাবে নেভিগেট করে তা নিশ্চিত করুন।
দারূন কাজ! আপনার অ্যাপটি গেম-সমাপ্ত ইভেন্টকে ট্রিগার করতে LiveData
থেকে গেমের GameViewModel
যোগাযোগ করতে LiveData ব্যবহার করে যে শব্দ তালিকাটি খালি রয়েছে। গেমের খণ্ডটি তারপর স্কোর খণ্ডে নেভিগেট করে।
এই টাস্কে, আপনি ScoreViewModel
এ একটি LiveData
অবজেক্টে স্কোর পরিবর্তন করুন এবং এতে একজন পর্যবেক্ষক সংযুক্ত করুন। আপনি যখন LiveData
এ GameViewModel
যোগ করেছিলেন তখন আপনি যা করেছিলেন এই কাজটি একই রকম।
আপনি সম্পূর্ণতার জন্য ScoreViewModel
এ এই পরিবর্তনগুলি করেন, যাতে আপনার অ্যাপের সমস্ত ডেটা LiveData
ব্যবহার করে।
-
ScoreViewModel
এ,score
ভেরিয়েবলের ধরনটিকেMutableLiveData
এ পরিবর্তন করুন।_score
এ এটির নাম পরিবর্তন করুন এবং একটি ব্যাকিং প্রপার্টি যোগ করুন।
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
get() = _score
-
ScoreViewModel
এ,init
ব্লকের ভিতরে,_score
শুরু করুন। আপনি আপনার পছন্দ মতোinit
ব্লকে লগটি সরাতে বা ছেড়ে দিতে পারেন।
init {
_score.value = finalScore
}
-
ScoreFragment
এ, onCreateViewonCreateView()
এর ভিতরে,viewModel
শুরু করার পর, স্কোরLiveData
অবজেক্টের জন্য একজন পর্যবেক্ষক সংযুক্ত করুন। ল্যাম্বডা এক্সপ্রেশনের ভিতরে, স্কোর টেক্সট ভিউতে স্কোর মান সেট করুন।ViewModel
থেকে স্কোর মান সহ পাঠ্য দৃশ্যকে সরাসরি বরাদ্দ করে এমন কোডটি সরান।
যোগ করার জন্য কোড:
// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
সরানোর জন্য কোড:
binding.scoreText.text = viewModel.score.toString()
Android Studio দ্বারা অনুরোধ করা হলে, androidx.lifecycle.Observer
আমদানি করুন।
- আপনার অ্যাপটি চালান এবং গেমটি খেলুন। অ্যাপটি আগের মতো কাজ করা উচিত, কিন্তু এখন এটি স্কোর আপডেট করতে
LiveData
এবং একজন পর্যবেক্ষক ব্যবহার করে।
এই টাস্কে, আপনি স্কোর স্ক্রিনে একটি প্লে এগেইন বোতাম যোগ করুন এবং একটি LiveData
ইভেন্ট ব্যবহার করে এটির ক্লিক শ্রোতাকে প্রয়োগ করুন। বোতামটি স্কোর স্ক্রীন থেকে গেম স্ক্রিনে নেভিগেট করার জন্য একটি ইভেন্টকে ট্রিগার করে।
অ্যাপের জন্য স্টার্টার কোডে প্লে এগেইন বোতাম রয়েছে, কিন্তু বোতামটি লুকানো আছে।
-
res/layout/score_fragment.xml
এ,play_again_button
বোতামের জন্য,visibility
বৈশিষ্ট্যের মানvisible
পরিবর্তন করুন।
<Button
android:id="@+id/play_again_button"
...
android:visibility="visible"
/>
-
ScoreViewModel
এ,_eventPlayAgain
নামকBoolean
ধরে রাখতে একটিLiveData
অবজেক্ট যোগ করুন। স্কোর স্ক্রীন থেকে গেম স্ক্রিনে নেভিগেট করতেLiveData
ইভেন্ট সংরক্ষণ করতে এই বস্তুটি ব্যবহার করা হয়।
private val _eventPlayAgain = MutableLiveData<Boolean>()
val eventPlayAgain: LiveData<Boolean>
get() = _eventPlayAgain
-
ScoreViewModel
এ, ইভেন্ট সেট এবং রিসেট করার পদ্ধতি সংজ্ঞায়িত করুন,_eventPlayAgain
।
fun onPlayAgain() {
_eventPlayAgain.value = true
}
fun onPlayAgainComplete() {
_eventPlayAgain.value = false
}
-
ScoreFragment
,eventPlayAgain
জন্য একজন পর্যবেক্ষক যোগ করুন।return
স্টেটমেন্টের আগেonCreateView()
এর শেষে কোডটি রাখুন। ল্যাম্বডা এক্সপ্রেশনের ভিতরে, গেম স্ক্রিনে ফিরে যান এবংeventPlayAgain
রিসেট করুন।
// Navigates back to game when button is pressed
viewModel.eventPlayAgain.observe(this, Observer { playAgain ->
if (playAgain) {
findNavController().navigate(ScoreFragmentDirections.actionRestart())
viewModel.onPlayAgainComplete()
}
})
androidx.navigation.fragment.findNavController
আমদানি করুন, যখন Android Studio দ্বারা প্রম্পট করা হবে।
-
ScoreFragment
এ, onCreateViewonCreateView()
এর ভিতরে, PlayAgain বোতামে একটি ক্লিক শ্রোতা যোগ করুন এবংviewModel
.onPlayAgain()
কল করুন।
binding.playAgainButton.setOnClickListener { viewModel.onPlayAgain() }
- আপনার অ্যাপটি চালান এবং গেমটি খেলুন। গেমটি শেষ হয়ে গেলে, স্কোর স্ক্রীন চূড়ান্ত স্কোর এবং আবার প্লে বোতামটি দেখায়। PlayAgain বোতামটি আলতো চাপুন, এবং অ্যাপটি গেম স্ক্রিনে নেভিগেট করে যাতে আপনি আবার গেমটি খেলতে পারেন।
ভাল কাজ! আপনি ViewModel-এ LiveData
অবজেক্ট ব্যবহার করতে আপনার অ্যাপের আর্কিটেকচার পরিবর্তন করেছেন এবং আপনি ViewModel
অবজেক্টের সাথে পর্যবেক্ষকদের সংযুক্ত LiveData
। LiveData
দ্বারা ধারণকৃত মান পরিবর্তিত হলে LiveData
পর্যবেক্ষক বস্তুকে অবহিত করে।
অ্যান্ড্রয়েড স্টুডিও প্রকল্প: GuessTheWord
লাইভডেটা
-
LiveData
হল একটি পর্যবেক্ষণযোগ্য ডেটা ধারক শ্রেণী যা জীবনচক্র-সচেতন, Android আর্কিটেকচার উপাদানগুলির মধ্যে একটি৷ - ডেটা আপডেট হলে স্বয়ংক্রিয়ভাবে আপডেট হতে আপনার UI সক্ষম করতে আপনি
LiveData
ব্যবহার করতে পারেন। -
LiveData
পর্যবেক্ষণযোগ্য, যার মানে হল যে কোনও ক্রিয়াকলাপ বা একটি খণ্ডের মতো একজন পর্যবেক্ষককে অবহিত করা যেতে পারে যখনLiveData
অবজেক্টের কাছে থাকা ডেটা পরিবর্তিত হয়। -
LiveData
ডেটা ধারণ করে; এটি একটি মোড়ক যা যেকোনো তথ্যের সাথে ব্যবহার করা যেতে পারে। -
LiveData
হল লাইফসাইকেল-সচেতন, মানে এটি শুধুমাত্র এমন পর্যবেক্ষকদের আপডেট করে যারা একটি সক্রিয় জীবনচক্র অবস্থায় আছে যেমনSTARTED
করা বাRESUMED
করা হয়েছে।
LiveData যোগ করতে
-
ViewModel
এ ডেটা ভেরিয়েবলের ধরনLiveData
বাMutableLiveData
এ পরিবর্তন করুন।
MutableLiveData
হল একটি LiveData
অবজেক্ট যার মান পরিবর্তন করা যায়। MutableLiveData
হল একটি জেনেরিক ক্লাস, তাই আপনাকে এটিতে থাকা ডেটার ধরন নির্দিষ্ট করতে হবে।
-
LiveData
দ্বারা ধারণকৃত ডেটার মান পরিবর্তন করতে,LiveData
ভেরিয়েবলেsetValue()
পদ্ধতি ব্যবহার করুন।
LiveData encapsulate করতে
-
LiveData
এর ভিতরে থাকাViewModel
সম্পাদনাযোগ্য হওয়া উচিত। ViewModel এর বাইরে,ViewModel
পাঠযোগ্যLiveData
উচিত। এটি একটি Kotlin ব্যাকিং সম্পত্তি ব্যবহার করে প্রয়োগ করা যেতে পারে। - একটি কোটলিন ব্যাকিং প্রপার্টি আপনাকে সঠিক বস্তু ব্যতীত অন্য কোনো গেটার থেকে কিছু ফেরত দিতে দেয়।
-
LiveData
এনক্যাপসুলেট করতে, ViewModel-এর ভিতরেprivate
MutableLiveData
ব্যবহার করুন এবংViewModel
এর বাইরে একটিLiveData
ব্যাকিং প্রপার্টিViewModel
।
পর্যবেক্ষণযোগ্য লাইভডেটা
-
LiveData
একটি পর্যবেক্ষক প্যাটার্ন অনুসরণ করে। "পর্যবেক্ষণযোগ্য" হলLiveData
অবজেক্ট, এবং পর্যবেক্ষক হল UI কন্ট্রোলারের পদ্ধতি, যেমন টুকরো টুকরো। যখনইLiveData
এর ভিতরে মোড়ানো ডেটা পরিবর্তিত হয়, UI কন্ট্রোলারগুলিতে পর্যবেক্ষক পদ্ধতিগুলিকে অবহিত করা হয়। -
LiveData
পর্যবেক্ষণযোগ্য করতে, পর্যবেক্ষণobserve()
পদ্ধতি ব্যবহার করে পর্যবেক্ষকদের (যেমন কার্যকলাপ এবং টুকরা)LiveData
রেফারেন্সের সাথে একটি পর্যবেক্ষক বস্তু সংযুক্ত করুন। - এই
LiveData
পর্যবেক্ষক প্যাটার্নটিViewModel
থেকে UI কন্ট্রোলারের সাথে যোগাযোগ করতে ব্যবহার করা যেতে পারে।
উদাসীনতা কোর্স:
অ্যান্ড্রয়েড ডেভেলপার ডকুমেন্টেশন:
অন্যান্য:
- কোটলিনে ব্যাকিং সম্পত্তি
এই বিভাগে একজন প্রশিক্ষকের নেতৃত্বে একটি কোর্সের অংশ হিসাবে এই কোডল্যাবের মাধ্যমে কাজ করা শিক্ষার্থীদের জন্য সম্ভাব্য হোমওয়ার্ক অ্যাসাইনমেন্ট তালিকাভুক্ত করা হয়েছে। নিম্নলিখিতগুলি করা প্রশিক্ষকের উপর নির্ভর করে:
- প্রয়োজনে হোমওয়ার্ক বরাদ্দ করুন।
- শিক্ষার্থীদের সাথে যোগাযোগ করুন কিভাবে হোমওয়ার্ক অ্যাসাইনমেন্ট জমা দিতে হয়।
- হোমওয়ার্ক অ্যাসাইনমেন্ট গ্রেড.
প্রশিক্ষকরা এই পরামর্শগুলি যতটা কম বা যতটা চান ততটা ব্যবহার করতে পারেন, এবং তাদের উপযুক্ত মনে করে অন্য কোনও হোমওয়ার্ক বরাদ্দ করতে নির্দ্বিধায় করা উচিত।
আপনি যদি এই কোডল্যাবের মাধ্যমে নিজে থেকে কাজ করে থাকেন, তাহলে আপনার জ্ঞান পরীক্ষা করার জন্য এই হোমওয়ার্ক অ্যাসাইনমেন্টগুলি ব্যবহার করুন।
এই প্রশ্নগুলোর উত্তর দাও
প্রশ্ন 1
আপনি কীভাবে একটি LiveData
সংরক্ষিত ViewModel
এনক্যাপসুলেট করবেন যাতে বাহ্যিক বস্তুগুলি আপডেট না করেই ডেটা পড়তে পারে?
-
ViewModel
অবজেক্টের ভিতরে, ডেটার ডেটা টাইপকেprivate
LiveData
পরিবর্তন করুন।MutableLiveData
প্রকারের শুধুমাত্র পঠনযোগ্য ডেটা প্রকাশ করতে একটি ব্যাকিং সম্পত্তি ব্যবহার করুন। -
ViewModel
অবজেক্টের ভিতরে, ডেটার ডেটা টাইপকেprivate
MutableLiveData
এ পরিবর্তন করুন।LiveData
প্রকারের শুধুমাত্র পঠনযোগ্য ডেটা প্রকাশ করতে একটি ব্যাকিং সম্পত্তি ব্যবহার করুন। - UI কন্ট্রোলারের ভিতরে, ডেটার ডেটা প্রকারকে
private
MutableLiveData
এ পরিবর্তন করুন।LiveData
প্রকারের শুধুমাত্র পঠনযোগ্য ডেটা প্রকাশ করতে একটি ব্যাকিং সম্পত্তি ব্যবহার করুন। -
ViewModel
অবজেক্টের ভিতরে, ডাটার ডাটা টাইপকেLiveData
এ পরিবর্তন করুন।LiveData
প্রকারের শুধুমাত্র পঠনযোগ্য ডেটা প্রকাশ করতে একটি ব্যাকিং সম্পত্তি ব্যবহার করুন।
প্রশ্ন 2
UI কন্ট্রোলার নিচের কোন LiveData
একটি UI কন্ট্রোলার (যেমন একটি খণ্ড) আপডেট করে?
- আবার শুরু হয়েছে
- পটভূমিতে
- বিরতি দেওয়া হয়েছে
- বন্ধ
প্রশ্ন 3
LiveData
পর্যবেক্ষক প্যাটার্নে, পর্যবেক্ষণযোগ্য আইটেমটি কী (কী পর্যবেক্ষণ করা হয়)?
- পর্যবেক্ষক পদ্ধতি
- একটি
LiveData
অবজেক্টের ডেটা - UI কন্ট্রোলার
-
ViewModel
অবজেক্ট
পরবর্তী পাঠ শুরু করুন:
এই কোর্সে অন্যান্য কোডল্যাবগুলির লিঙ্কগুলির জন্য, Android Kotlin Fundamentals codelabs ল্যান্ডিং পৃষ্ঠাটি দেখুন।