यह कोडलैब, Android Kotlin Fundamentals कोर्स का हिस्सा है. अगर कोडलैब को क्रम से पूरा किया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा. कोर्स के सभी कोडलैब, Android Kotlin Fundamentals कोडलैब के लैंडिंग पेज पर दिए गए हैं.
परिचय
इस लेसन के पिछले कोडलैब में, आपने GuessTheWord ऐप्लिकेशन के कोड को बेहतर बनाया था. अब ऐप्लिकेशन, ViewModel
ऑब्जेक्ट का इस्तेमाल करता है. इसलिए, डिवाइस के कॉन्फ़िगरेशन में बदलाव होने पर भी ऐप्लिकेशन का डेटा सुरक्षित रहता है. जैसे, स्क्रीन रोटेशन और कीबोर्ड की उपलब्धता में बदलाव. आपने ऑब्ज़र्वेबल LiveData
भी जोड़ा है. इसलिए, जब ऑब्ज़र्व किए गए डेटा में बदलाव होता है, तो व्यू को अपने-आप सूचना मिल जाती है.
इस कोडलैब में, आपको GuessTheWord ऐप्लिकेशन के साथ काम करना जारी रखना है. आपको ऐप्लिकेशन में मौजूद ViewModel
क्लास से व्यू बाइंड करने हैं, ताकि आपके लेआउट में मौजूद व्यू सीधे ViewModel
ऑब्जेक्ट से कम्यूनिकेट कर सकें. (अब तक आपके ऐप्लिकेशन में, व्यू, ऐप्लिकेशन के फ़्रैगमेंट के ज़रिए ViewModel
के साथ अप्रत्यक्ष रूप से कम्यूनिकेट करते थे.) ViewModel
ऑब्जेक्ट के साथ डेटा बाइंडिंग को इंटिग्रेट करने के बाद, आपको ऐप्लिकेशन के फ़्रैगमेंट में क्लिक हैंडलर की ज़रूरत नहीं होती. इसलिए, उन्हें हटा दें.
इसके अलावा, GuessTheWord ऐप्लिकेशन में भी बदलाव किया जाता है, ताकि डेटा-बाइंडिंग सोर्स के तौर पर LiveData
का इस्तेमाल किया जा सके. इससे यूज़र इंटरफ़ेस (यूआई) को डेटा में हुए बदलावों के बारे में सूचना दी जा सके. इसके लिए, LiveData
ऑब्ज़र्वर के तरीकों का इस्तेमाल नहीं किया जाता.
आपको पहले से क्या पता होना चाहिए
- Kotlin में बुनियादी Android ऐप्लिकेशन बनाने का तरीका.
- ऐक्टिविटी और फ़्रैगमेंट की लाइफ़साइकल कैसे काम करती हैं.
- अपने ऐप्लिकेशन में
ViewModel
ऑब्जेक्ट इस्तेमाल करने का तरीका. ViewModel
मेंLiveData
का इस्तेमाल करके डेटा सेव करने का तरीका.LiveData
डेटा में हुए बदलावों को देखने के लिए, ऑब्ज़र्वर के तरीके कैसे जोड़ें.
आपको क्या सीखने को मिलेगा
- डेटा बाइंडिंग लाइब्रेरी के एलिमेंट इस्तेमाल करने का तरीका.
- डेटा बाइंडिंग के साथ
ViewModel
को इंटिग्रेट करने का तरीका. - डेटा बाइंडिंग के साथ
LiveData
को इंटिग्रेट करने का तरीका. - किसी फ़्रैगमेंट में क्लिक लिसनर बदलने के लिए, लिसनर बाइंडिंग का इस्तेमाल कैसे करें.
- डेटा-बाइंडिंग एक्सप्रेशन में स्ट्रिंग फ़ॉर्मैटिंग जोड़ने का तरीका.
आपको क्या करना होगा
- GuessTheWord लेआउट में मौजूद व्यू,
ViewModel
ऑब्जेक्ट के साथ सीधे तौर पर कम्यूनिकेट नहीं करते. वे जानकारी को रिले करने के लिए, यूज़र इंटरफ़ेस (यूआई) कंट्रोलर (फ़्रैगमेंट) का इस्तेमाल करते हैं. इस कोडलैब में, ऐप्लिकेशन के व्यू कोViewModel
ऑब्जेक्ट से बाइंड किया जाता है, ताकि व्यू,ViewModel
ऑब्जेक्ट के साथ सीधे कम्यूनिकेट कर सकें. - इसके बाद, ऐप्लिकेशन को
LiveData
को डेटा-बाइंडिंग सोर्स के तौर पर इस्तेमाल करने के लिए बदला जाता है. इस बदलाव के बाद,LiveData
ऑब्जेक्ट, यूज़र इंटरफ़ेस (यूआई) को डेटा में हुए बदलावों के बारे में सूचना देते हैं. साथ ही,LiveData
ऑब्ज़र्वर के तरीकों की अब ज़रूरत नहीं होती.
पांचवें लेसन के कोडलैब में, आपको GuessTheWord ऐप्लिकेशन बनाना है. इसके लिए, आपको स्टार्टर कोड से शुरुआत करनी होगी. GuessTheWord, दो खिलाड़ियों वाला शराबी गेम है. इसमें खिलाड़ी मिलकर, ज़्यादा से ज़्यादा स्कोर हासिल करने की कोशिश करते हैं.
पहला खिलाड़ी, ऐप्लिकेशन में दिए गए शब्दों को देखता है और एक-एक करके उन पर ऐक्ट करता है. वह यह पक्का करता है कि दूसरा खिलाड़ी उन शब्दों को न देख पाए. दूसरा खिलाड़ी, शब्द का अनुमान लगाने की कोशिश करता है.
गेम खेलने के लिए, पहला खिलाड़ी डिवाइस पर ऐप्लिकेशन खोलता है और उसे एक शब्द दिखता है. उदाहरण के लिए, "गिटार". यह शब्द, नीचे दिए गए स्क्रीनशॉट में दिखाया गया है.
पहला खिलाड़ी, शब्द को बोलकर नहीं, बल्कि ऐक्टिंग करके बताता है.
- जब दूसरा खिलाड़ी शब्द का सही अनुमान लगा लेता है, तब पहला खिलाड़ी समझ गया बटन दबाता है. इससे स्कोर में एक पॉइंट जुड़ जाता है और अगला शब्द दिखता है.
- अगर दूसरा प्लेयर शब्द का अनुमान नहीं लगा पाता है, तो पहला प्लेयर छोड़ें बटन दबाता है. इससे शब्द की संख्या एक कम हो जाती है और अगले शब्द पर पहुंच जाता है.
- गेम खत्म करने के लिए, गेम खत्म करें बटन दबाएं. (यह सुविधा, सीरीज़ के पहले कोडलैब के स्टार्टर कोड में नहीं है.)
इस कोडलैब में, LiveData
ऑब्जेक्ट में LiveData
के साथ डेटा बाइंडिंग को इंटिग्रेट करके, GuessTheWord ऐप्लिकेशन को बेहतर बनाया जाता है.ViewModel
इससे लेआउट में मौजूद व्यू और ViewModel
ऑब्जेक्ट के बीच कम्यूनिकेशन अपने-आप हो जाता है. साथ ही, LiveData
का इस्तेमाल करके, अपने कोड को आसान बनाया जा सकता है.
शीर्षक स्क्रीन | गेम की स्क्रीन | स्कोर स्क्रीन |
इस टास्क में, आपको इस कोडलैब के लिए स्टार्टर कोड ढूंढना और उसे चलाना है. पिछले कोडलैब में बनाए गए GuessTheWord ऐप्लिकेशन को स्टार्टर कोड के तौर पर इस्तेमाल किया जा सकता है. इसके अलावा, स्टार्टर ऐप्लिकेशन भी डाउनलोड किया जा सकता है.
- (ज़रूरी नहीं) अगर आपको पिछले कोडलैब का कोड इस्तेमाल नहीं करना है, तो इस कोडलैब के लिए स्टार्टर कोड डाउनलोड करें. कोड को अनज़िप करें और Android Studio में प्रोजेक्ट खोलें.
- ऐप्लिकेशन चलाएं और गेम खेलें.
- ध्यान दें कि ठीक है बटन पर क्लिक करने से, अगला शब्द दिखता है और स्कोर में एक पॉइंट जुड़ जाता है. वहीं, अभी नहीं बटन पर क्लिक करने से, अगला शब्द दिखता है और स्कोर में एक पॉइंट कम हो जाता है. गेम खत्म करें बटन से गेम खत्म हो जाता है.
- सभी शब्दों को एक-एक करके देखें. ध्यान दें कि ऐप्लिकेशन, स्कोर वाली स्क्रीन पर अपने-आप पहुंच जाता है.
पिछले कोडलैब में, आपने GuessTheWord ऐप्लिकेशन में व्यू ऐक्सेस करने के लिए, टाइप-सेफ़ तरीके के तौर पर डेटा बाइंडिंग का इस्तेमाल किया था. हालांकि, डेटा बाइंडिंग का असली फ़ायदा यह है कि यह नाम के मुताबिक काम करती है. यानी, यह आपके ऐप्लिकेशन में व्यू ऑब्जेक्ट के साथ डेटा को सीधे तौर पर बाइंड करती है.
ऐप्लिकेशन का मौजूदा आर्किटेक्चर
आपके ऐप्लिकेशन में, व्यू को XML लेआउट में तय किया जाता है. साथ ही, उन व्यू का डेटा ViewModel
ऑब्जेक्ट में सेव किया जाता है. हर व्यू और उससे जुड़े ViewModel
के बीच एक यूज़र इंटरफ़ेस (यूआई) कंट्रोलर होता है. यह इन दोनों के बीच रिले के तौर पर काम करता है.
उदाहरण के लिए:
- ठीक है बटन को
game_fragment.xml
लेआउट फ़ाइल मेंButton
व्यू के तौर पर तय किया गया है. - जब उपयोगकर्ता ठीक है बटन पर टैप करता है, तब
GameFragment
फ़्रैगमेंट में मौजूद क्लिक लिसनर,GameViewModel
में मौजूद क्लिक लिसनर को कॉल करता है. - स्कोर को
GameViewModel
में अपडेट किया जाता है.
Button
व्यू और GameViewModel
सीधे तौर पर कम्यूनिकेट नहीं करते. इसके लिए, उन्हें GameFragment
में मौजूद क्लिक लिसनर की ज़रूरत होती है.
डेटा बाइंडिंग में पास किया गया ViewModel
लेआउट में, अगर व्यू, यूज़र इंटरफ़ेस (यूआई) कंट्रोलर के बजाय सीधे ViewModel
ऑब्जेक्ट में मौजूद डेटा से कम्यूनिकेट करें, तो प्रोसेस ज़्यादा आसान होगी.
ViewModel
ऑब्जेक्ट, GuessTheWord ऐप्लिकेशन में यूज़र इंटरफ़ेस (यूआई) का पूरा डेटा सेव रखते हैं. डेटा बाइंडिंग में ViewModel
ऑब्जेक्ट पास करके, व्यू और ViewModel
ऑब्जेक्ट के बीच कुछ कम्यूनिकेशन ऑटोमेट किया जा सकता है.
इस टास्क में, GameViewModel
और ScoreViewModel
क्लास को उनके एक्सएमएल लेआउट से जोड़ा जाता है. आपने क्लिक इवेंट को मैनेज करने के लिए, लिसनर बाइंडिंग भी सेट अप की हैं.
पहला चरण: GameViewModel के लिए डेटा बाइंडिंग जोड़ना
इस चरण में, GameViewModel
को उससे जुड़ी लेआउट फ़ाइल, game_fragment.xml
से जोड़ा जाता है.
game_fragment.xml
फ़ाइल में,GameViewModel
टाइप का डेटा-बाइंडिंग वैरिएबल जोड़ें. अगर आपको Android Studio में गड़बड़ियां दिख रही हैं, तो प्रोजेक्ट को क्लीन और रीबिल्ड करें.
<layout ...>
<data>
<variable
name="gameViewModel"
type="com.example.android.guesstheword.screens.game.GameViewModel" />
</data>
<androidx.constraintlayout...
GameFragment
फ़ाइल में,GameViewModel
को डेटा बाइंडिंग में पास करें.
इसके लिए,viewModel
कोbinding.gameViewModel
वैरिएबल असाइन करें. यह वैरिएबल आपने पिछले चरण में घोषित किया था. इस कोड कोviewModel
के शुरू होने के बाद,onCreateView()
में डालें. अगर आपको Android Studio में गड़बड़ियां दिख रही हैं, तो प्रोजेक्ट को क्लीन और रीबिल्ड करें.
// Set the viewmodel for databinding - this allows the bound layout access
// to all the data in the ViewModel
binding.gameViewModel = viewModel
दूसरा चरण: इवेंट हैंडलिंग के लिए लिसनर बाइंडिंग का इस्तेमाल करना
लिसनर बाइंडिंग, बाइंडिंग एक्सप्रेशन होते हैं. ये onClick()
, onZoomIn()
या onZoomOut()
जैसे इवेंट ट्रिगर होने पर काम करते हैं. लिसनर बाइंडिंग को लैम्डा एक्सप्रेशन के तौर पर लिखा जाता है.
डेटा बाइंडिंग, एक लिसनर बनाती है और उसे व्यू पर सेट करती है. जब लिसन किया गया इवेंट होता है, तो लिसनर, लैम्डा एक्सप्रेशन का आकलन करता है. लिसनर बाइंडिंग, Android Gradle प्लगिन 2.0 या इसके बाद के वर्शन के साथ काम करती हैं. ज़्यादा जानने के लिए, लेआउट और बाइंडिंग एक्सप्रेशन पढ़ें.
इस चरण में, GameFragment
में मौजूद क्लिक लिसनर को game_fragment.xml
फ़ाइल में मौजूद लिसनर बाइंडिंग से बदला जाता है.
game_fragment.xml
में,skip_button
मेंonClick
एट्रिब्यूट जोड़ें. बाइंडिंग एक्सप्रेशन तय करें औरGameViewModel
मेंonSkip()
वाले तरीके को कॉल करें. इस बाइंडिंग एक्सप्रेशन को लिसनर बाइंडिंग कहा जाता है.
<Button
android:id="@+id/skip_button"
...
android:onClick="@{() -> gameViewModel.onSkip()}"
... />
- इसी तरह,
correct_button
के क्लिक इवेंट कोGameViewModel
में मौजूदonCorrect
()
तरीके से बाइंड करें.
<Button
android:id="@+id/correct_button"
...
android:onClick="@{() -> gameViewModel.onCorrect()}"
... />
end_game_button
के क्लिक इवेंट कोGameViewModel
में मौजूदonGameFinish
()
तरीके से बाइंड करें.
<Button
android:id="@+id/end_game_button"
...
android:onClick="@{() -> gameViewModel.onGameFinish()}"
... />
GameFragment
में, क्लिक लिसनर सेट करने वाले स्टेटमेंट हटाएं. साथ ही, क्लिक लिसनर कॉल करने वाले फ़ंक्शन हटाएं. अब आपको उनकी ज़रूरत नहीं है.
हटाने के लिए कोड:
binding.correctButton.setOnClickListener { onCorrect() }
binding.skipButton.setOnClickListener { onSkip() }
binding.endGameButton.setOnClickListener { onEndGame() }
/** Methods for buttons presses **/
private fun onSkip() {
viewModel.onSkip()
}
private fun onCorrect() {
viewModel.onCorrect()
}
private fun onEndGame() {
gameFinished()
}
तीसरा चरण: ScoreViewModel के लिए डेटा बाइंडिंग जोड़ना
इस चरण में, ScoreViewModel
को उससे जुड़ी लेआउट फ़ाइल, score_fragment.xml
से जोड़ा जाता है.
score_fragment.xml
फ़ाइल में,ScoreViewModel
टाइप का बाइंडिंग वैरिएबल जोड़ें. यह चरण, ऊपर दिए गएGameViewModel
चरण की तरह ही है.
<layout ...>
<data>
<variable
name="scoreViewModel"
type="com.example.android.guesstheword.screens.score.ScoreViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
score_fragment.xml
में,play_again_button
मेंonClick
एट्रिब्यूट जोड़ें. लिसनर बाइंडिंग तय करें औरScoreViewModel
मेंonPlayAgain()
तरीके को कॉल करें.
<Button
android:id="@+id/play_again_button"
...
android:onClick="@{() -> scoreViewModel.onPlayAgain()}"
... />
ScoreFragment
में,onCreateView()
के अंदर,viewModel
को शुरू करें. इसके बाद,binding.scoreViewModel
बाइंडिंग वैरिएबल को शुरू करें.
viewModel = ...
binding.scoreViewModel = viewModel
ScoreFragment
में,playAgainButton
के लिए क्लिक लिसनर सेट करने वाला कोड हटाएं. अगर Android Studio में कोई गड़बड़ी दिखती है, तो प्रोजेक्ट को क्लीन और रीबिल्ड करें.
हटाने के लिए कोड:
binding.playAgainButton.setOnClickListener { viewModel.onPlayAgain() }
- अपना ऐप्लिकेशन चलाएं. ऐप्लिकेशन पहले की तरह काम करेगा. हालांकि, अब बटन व्यू सीधे तौर पर
ViewModel
ऑब्जेक्ट के साथ कम्यूनिकेट करते हैं. अब व्यू,ScoreFragment
में बटन क्लिक हैंडलर के ज़रिए कम्यूनिकेट नहीं करते हैं.
डेटा-बाइंडिंग से जुड़ी गड़बड़ी के मैसेज की समस्या हल करना
जब कोई ऐप्लिकेशन डेटा बाइंडिंग का इस्तेमाल करता है, तो कंपाइलेशन प्रोसेस, इंटरमीडिएट क्लास जनरेट करती है. इनका इस्तेमाल डेटा बाइंडिंग के लिए किया जाता है. किसी ऐप्लिकेशन में ऐसी गड़बड़ियां हो सकती हैं जिन्हें Android Studio तब तक नहीं पहचान पाता, जब तक ऐप्लिकेशन को कंपाइल नहीं किया जाता. इसलिए, कोड लिखते समय आपको चेतावनियां या लाल रंग का कोड नहीं दिखता. हालांकि, कंपाइल करने के समय, आपको ऐसी गड़बड़ियां दिखती हैं जिन्हें समझना मुश्किल होता है. ये गड़बड़ियां, जनरेट की गई इंटरमीडिएट क्लास से मिलती हैं.
अगर आपको गड़बड़ी का ऐसा मैसेज मिलता है जिसे समझना मुश्किल है, तो:
- Android Studio के Build पैन में मौजूद मैसेज को ध्यान से देखें. अगर आपको कोई ऐसी जगह दिखती है जिसके आखिर में
databinding
लिखा है, तो इसका मतलब है कि डेटा बाइंडिंग में कोई गड़बड़ी हुई है. - लेआउट एक्सएमएल फ़ाइल में, डेटा बाइंडिंग का इस्तेमाल करने वाले
onClick
एट्रिब्यूट में गड़बड़ियां देखें. उस फ़ंक्शन को ढूंढें जिसे लैम्डा एक्सप्रेशन कॉल करता है. साथ ही, पक्का करें कि वह फ़ंक्शन मौजूद हो. - एक्सएमएल के
<data>
सेक्शन में, डेटा-बाइंडिंग वैरिएबल की स्पेलिंग देखें.
उदाहरण के लिए, एट्रिब्यूट की इस वैल्यू में फ़ंक्शन के नाम onCorrect()
की स्पेलिंग गलत है:
android:onClick="@{() -> gameViewModel.onCorrectx()}"
एक्सएमएल फ़ाइल के <data>
सेक्शन में, gameViewModel
की स्पेलिंग गलत है:
<data>
<variable
name="gameViewModelx"
type="com.example.android.guesstheword.screens.game.GameViewModel" />
</data>
Android Studio, ऐप्लिकेशन को कंपाइल करने से पहले इस तरह की गड़बड़ियों का पता नहीं लगाता. इसके बाद, कंपाइलर गड़बड़ी का यह मैसेज दिखाता है:
error: cannot find symbol import com.example.android.guesstheword.databinding.GameFragmentBindingImpl" symbol: class GameFragmentBindingImpl location: package com.example.android.guesstheword.databinding
डेटा बाइंडिंग, ViewModel
ऑब्जेक्ट के साथ इस्तेमाल किए जाने वाले LiveData
के साथ अच्छी तरह से काम करती है. ViewModel
ऑब्जेक्ट में डेटा बाइंडिंग जोड़ने के बाद, अब LiveData
को शामिल किया जा सकता है.
इस टास्क में, आपको GuessTheWord ऐप्लिकेशन में LiveData
को डेटा-बाइंडिंग सोर्स के तौर पर इस्तेमाल करने के लिए बदलना है. इससे यूज़र इंटरफ़ेस (यूआई) को डेटा में हुए बदलावों के बारे में सूचना मिलती है. इसके लिए, LiveData
ऑब्ज़र्वर के तरीकों का इस्तेमाल नहीं किया जाता.
पहला चरण: game_fragment.xml फ़ाइल में LiveData शब्द जोड़ना
इस चरण में, मौजूदा शब्द के टेक्स्ट व्यू को सीधे तौर पर LiveData
में मौजूद ViewModel
ऑब्जेक्ट से बाइंड किया जाता है.
game_fragment.xml
में,word_text
टेक्स्ट व्यू मेंandroid:text
एट्रिब्यूट जोड़ें.
इसे LiveData
ऑब्जेक्ट पर सेट करें. इसके लिए, GameViewModel
से word
का इस्तेमाल करें. साथ ही, बाइंडिंग वैरिएबल gameViewModel
का इस्तेमाल करें.
<TextView
android:id="@+id/word_text"
...
android:text="@{gameViewModel.word}"
... />
ध्यान दें कि आपको word.value
का इस्तेमाल करने की ज़रूरत नहीं है. इसके बजाय, असल LiveData
ऑब्जेक्ट का इस्तेमाल किया जा सकता है. LiveData
ऑब्जेक्ट, word
की मौजूदा वैल्यू दिखाता है. अगर word
की वैल्यू शून्य है, तो LiveData
ऑब्जेक्ट एक खाली स्ट्रिंग दिखाता है.
GameFragment
में,onCreateView()
में,gameViewModel
को शुरू करने के बाद, मौजूदा ऐक्टिविटी कोbinding
वैरिएबल के लाइफ़साइकल के मालिक के तौर पर सेट करें. इससे ऊपर दिए गएLiveData
ऑब्जेक्ट का स्कोप तय होता है. इससे ऑब्जेक्ट, लेआउटgame_fragment.xml
में व्यू अपने-आप अपडेट कर पाता है.
binding.gameViewModel = ...
// Specify the current activity as the lifecycle owner of the binding.
// This is used so that the binding can observe LiveData updates
binding.lifecycleOwner = this
GameFragment
में,LiveData
word
के लिए ऑब्ज़र्वर को हटाएं.
हटाने के लिए कोड:
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
binding.wordText.text = newWord
})
- अपना ऐप्लिकेशन चलाएं और गेम खेलें. अब मौजूदा शब्द को UI कंट्रोलर में ऑब्ज़र्वर तरीके के बिना अपडेट किया जा रहा है.
दूसरा चरण: score_fragment.xml फ़ाइल में score LiveData जोड़ना
इस चरण में, LiveData
score
को स्कोर फ़्रैगमेंट में मौजूद स्कोर टेक्स्ट व्यू से बाइंड किया जाता है.
score_fragment.xml
में, स्कोर टेक्स्ट व्यू मेंandroid:text
एट्रिब्यूट जोड़ें.text
एट्रिब्यूट के लिएscoreViewModel.score
असाइन करें.score
एक पूर्णांक है. इसलिए, इसेString.valueOf()
का इस्तेमाल करके स्ट्रिंग में बदलें.
<TextView
android:id="@+id/score_text"
...
android:text="@{String.valueOf(scoreViewModel.score)}"
... />
ScoreFragment
में,scoreViewModel
को शुरू करने के बाद, मौजूदा ऐक्टिविटी कोbinding
वैरिएबल के लाइफ़साइकल के मालिक के तौर पर सेट करें.
binding.scoreViewModel = ...
// Specify the current activity as the lifecycle owner of the binding.
// This is used so that the binding can observe LiveData updates
binding.lifecycleOwner = this
ScoreFragment
में,score
ऑब्जेक्ट के लिए ऑब्ज़र्वर हटाएं.
हटाने के लिए कोड:
// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
- अपना ऐप्लिकेशन चलाएं और गेम खेलें. ध्यान दें कि स्कोर फ़्रैगमेंट में स्कोर सही तरीके से दिखाया गया है. साथ ही, स्कोर फ़्रैगमेंट में कोई ऑब्ज़र्वर मौजूद नहीं है.
तीसरा चरण: डेटा बाइंडिंग के साथ स्ट्रिंग फ़ॉर्मैटिंग जोड़ना
लेआउट में, डेटा बाइंडिंग के साथ-साथ स्ट्रिंग फ़ॉर्मैटिंग भी जोड़ी जा सकती है. इस टास्क में, आपको मौजूदा शब्द को फ़ॉर्मैट करना है, ताकि उसके चारों ओर कोटेशन मार्क जोड़े जा सकें. स्कोर स्ट्रिंग को इस तरह से फ़ॉर्मैट करें कि उसके आगे मौजूदा स्कोर लिखा हो. इसके लिए, यहां दी गई इमेज देखें.
string.xml
में, ये स्ट्रिंग जोड़ें. इनका इस्तेमालword
औरscore
टेक्स्ट व्यू को फ़ॉर्मैट करने के लिए किया जाएगा.%s
और%d
, मौजूदा शब्द और मौजूदा स्कोर के लिए प्लेसहोल्डर हैं.
<string name="quote_format">\"%s\"</string>
<string name="score_format">Current Score: %d</string>
game_fragment.xml
में,quote_format
स्ट्रिंग रिसॉर्स का इस्तेमाल करने के लिए,word_text
टेक्स्ट व्यू केtext
एट्रिब्यूट को अपडेट करें.gameViewModel.word
से आगे बढ़ें. इससे मौजूदा शब्द को फ़ॉर्मैटिंग स्ट्रिंग के लिए आर्ग्युमेंट के तौर पर पास किया जाता है.
<TextView
android:id="@+id/word_text"
...
android:text="@{@string/quote_format(gameViewModel.word)}"
... />
score
टेक्स्ट व्यू कोword_text
की तरह फ़ॉर्मैट करें.game_fragment.xml
में,score_text
टेक्स्ट व्यू मेंtext
एट्रिब्यूट जोड़ें. स्ट्रिंग रिसोर्सscore_format
का इस्तेमाल करें. यह एक संख्यात्मक तर्क लेता है, जिसे%d
प्लेसहोल्डर के तौर पर दिखाया जाता है.LiveData
ऑब्जेक्टscore
को इस फ़ॉर्मैटिंग स्ट्रिंग के आर्ग्युमेंट के तौर पर पास करें.
<TextView
android:id="@+id/score_text"
...
android:text="@{@string/score_format(gameViewModel.score)}"
... />
GameFragment
क्लास में,onCreateView()
मैथड के अंदर,score
ऑब्ज़र्वर कोड हटाएं.
हटाने के लिए कोड:
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
- अपने ऐप्लिकेशन को क्लीन करें, फिर से बनाएं, और चलाएं. इसके बाद, गेम खेलें. ध्यान दें कि गेम की स्क्रीन पर, मौजूदा शब्द और स्कोर को फ़ॉर्मैट किया गया है.
बधाई हो! आपने अपने ऐप्लिकेशन में डेटा बाइंडिंग के साथ LiveData
और ViewModel
को इंटिग्रेट किया है. इससे आपके लेआउट में मौजूद व्यू, फ़्रैगमेंट में क्लिक हैंडलर का इस्तेमाल किए बिना सीधे ViewModel
से कम्यूनिकेट कर सकते हैं. आपने LiveData
ऑब्जेक्ट का इस्तेमाल, डेटा बाइंडिंग सोर्स के तौर पर भी किया है. इससे यूज़र इंटरफ़ेस (यूआई) को डेटा में हुए बदलावों के बारे में अपने-आप सूचना मिलती है. इसके लिए, LiveData
ऑब्ज़र्वर के तरीकों का इस्तेमाल नहीं किया जाता.
Android Studio प्रोजेक्ट: GuessTheWord
- डेटा बाइंडिंग लाइब्रेरी, Android के आर्किटेक्चर कॉम्पोनेंट के साथ आसानी से काम करती है. जैसे,
ViewModel
औरLiveData
. - आपके ऐप्लिकेशन में मौजूद लेआउट, आर्किटेक्चर कॉम्पोनेंट में मौजूद डेटा से बाइंड हो सकते हैं. ये कॉम्पोनेंट, यूज़र इंटरफ़ेस (यूआई) कंट्रोलर के लाइफ़साइकल को मैनेज करने और डेटा में होने वाले बदलावों के बारे में सूचना देने में आपकी मदद करते हैं.
ViewModel डेटा बाइंडिंग
- डेटा बाइंडिंग का इस्तेमाल करके, किसी लेआउट के साथ
ViewModel
को जोड़ा जा सकता है. ViewModel
ऑब्जेक्ट में यूज़र इंटरफ़ेस (यूआई) का डेटा होता है. डेटा बाइंडिंग मेंViewModel
ऑब्जेक्ट पास करके, व्यू औरViewModel
ऑब्जेक्ट के बीच कुछ कम्यूनिकेशन ऑटोमेट किए जा सकते हैं.
किसी लेआउट के साथ ViewModel
को कैसे जोड़ा जाता है:
- लेआउट फ़ाइल में,
ViewModel
टाइप का डेटा-बाइंडिंग वैरिएबल जोड़ें.
<data>
<variable
name="gameViewModel"
type="com.example.android.guesstheword.screens.game.GameViewModel" />
</data>
GameFragment
फ़ाइल में,GameViewModel
को डेटा बाइंडिंग में पास करें.
binding.gameViewModel = viewModel
लिसनर बाइंडिंग
- लिसनर बाइंडिंग, लेआउट में बाइंडिंग एक्सप्रेशन होते हैं. ये तब चलते हैं, जब
onClick()
जैसे क्लिक इवेंट ट्रिगर होते हैं. - लिसनर बाइंडिंग को लैम्डा एक्सप्रेशन के तौर पर लिखा जाता है.
- लिसनर बाइंडिंग का इस्तेमाल करके, यूज़र इंटरफ़ेस (यूआई) कंट्रोलर में मौजूद क्लिक लिसनर को लेआउट फ़ाइल में मौजूद लिसनर बाइंडिंग से बदलें.
- डेटा बाइंडिंग, एक लिसनर बनाती है और उसे व्यू पर सेट करती है.
android:onClick="@{() -> gameViewModel.onSkip()}"
डेटा बाइंडिंग में LiveData जोड़ना
LiveData
ऑब्जेक्ट का इस्तेमाल, डेटा-बाइंडिंग सोर्स के तौर पर किया जा सकता है. इससे डेटा में हुए बदलावों के बारे में यूज़र इंटरफ़ेस (यूआई) को अपने-आप सूचना मिल जाती है.- व्यू को सीधे तौर पर
ViewModel
में मौजूदLiveData
ऑब्जेक्ट से बाइंड किया जा सकता है.ViewModel
में बदलाव होने पर, लेआउट में मौजूद व्यू अपने-आप अपडेट हो सकते हैं. इसके लिए, यूज़र इंटरफ़ेस (यूआई) कंट्रोलर में ऑब्ज़र्वर के तरीकों की ज़रूरत नहीं होती.LiveData
android:text="@{gameViewModel.word}"
LiveData
डेटा बाइंडिंग को काम करने के लिए, मौजूदा ऐक्टिविटी (यूज़र इंटरफ़ेस (यूआई) कंट्रोलर) को यूज़र इंटरफ़ेस (यूआई) कंट्रोलर मेंLiveData
वैरिएबल के लाइफ़साइकल के मालिक के तौर पर सेट करें.binding
binding.lifecycleOwner = this
डेटा बाइंडिंग के साथ स्ट्रिंग फ़ॉर्मैटिंग
- डेटा बाइंडिंग का इस्तेमाल करके, स्ट्रिंग रिसॉर्स को फ़ॉर्मैट किया जा सकता है. इसके लिए, स्ट्रिंग के लिए
%s
और पूर्णांक के लिए%d
जैसे प्लेसहोल्डर का इस्तेमाल किया जा सकता है. - व्यू के
text
एट्रिब्यूट को अपडेट करने के लिए, फ़ॉर्मैटिंग स्ट्रिंग मेंtext
ऑब्जेक्ट को आर्ग्युमेंट के तौर पर पास करें.LiveData
android:text="@{@string/quote_format(gameViewModel.word)}"
Udacity का कोर्स:
Android डेवलपर का दस्तावेज़:
इस सेक्शन में, उन छात्र-छात्राओं के लिए होमवर्क असाइनमेंट की सूची दी गई है जो किसी शिक्षक के कोर्स के हिस्से के तौर पर इस कोडलैब पर काम कर रहे हैं. शिक्षक के पास ये विकल्प होते हैं:
- अगर ज़रूरी हो, तो होमवर्क असाइन करें.
- छात्र-छात्राओं को बताएं कि होमवर्क असाइनमेंट कैसे सबमिट किए जाते हैं.
- होमवर्क असाइनमेंट को ग्रेड दें.
शिक्षक इन सुझावों का इस्तेमाल अपनी ज़रूरत के हिसाब से कर सकते हैं. साथ ही, वे चाहें, तो कोई दूसरा होमवर्क भी दे सकते हैं.
अगर आपको यह कोडलैब खुद से पूरा करना है, तो अपनी जानकारी की जांच करने के लिए, इन होमवर्क असाइनमेंट का इस्तेमाल करें.
इन सवालों के जवाब दें
पहला सवाल
लिसनर बाइंडिंग के बारे में इनमें से कौनसी बात सही नहीं है?
- लिसनर बाइंडिंग, बाइंडिंग एक्सप्रेशन होते हैं. ये किसी इवेंट के होने पर चलते हैं.
- लिसनर बाइंडिंग, Android Gradle प्लग-इन के सभी वर्शन के साथ काम करती हैं.
- लिसनर बाइंडिंग को लैम्डा एक्सप्रेशन के तौर पर लिखा जाता है.
- लिसनर बाइंडिंग, मेथड रेफ़रंस की तरह ही होती हैं. हालांकि, इनकी मदद से डेटा-बाइंडिंग के किसी भी एक्सप्रेशन को चलाया जा सकता है.
दूसरा सवाल
मान लें कि आपके ऐप्लिकेशन में यह स्ट्रिंग संसाधन शामिल है:<string name="generic_name">Hello %s</string>
डेटा-बाइंडिंग एक्सप्रेशन का इस्तेमाल करके स्ट्रिंग को फ़ॉर्मैट करने के लिए, इनमें से कौनसा सिंटैक्स सही है?
android:text= "@{@string/generic_name(user.name)}"
android:text= "@{string/generic_name(user.name)}"
android:text= "@{@generic_name(user.name)}"
android:text= "@{@string/generic_name,user.name}"
तीसरा सवाल
लिसनर-बाइंडिंग एक्सप्रेशन का आकलन कब किया जाता है और इसे कब चलाया जाता है?
- जब
LiveData
में मौजूद डेटा बदल जाता है - जब कॉन्फ़िगरेशन में बदलाव की वजह से किसी ऐक्टिविटी को फिर से बनाया जाता है
- जब
onClick()
जैसा कोई इवेंट होता है - जब गतिविधि बैकग्राउंड में चली जाती है
अगला लेसन शुरू करें:
इस कोर्स में मौजूद अन्य कोडलैब के लिंक के लिए, Android Kotlin Fundamentals कोडलैब का लैंडिंग पेज देखें.