यह कोडलैब, Android Kotlin Fundamentals कोर्स का हिस्सा है. अगर कोडलैब को क्रम से पूरा किया जाता है, तो आपको इस कोर्स से सबसे ज़्यादा फ़ायदा मिलेगा. कोर्स के सभी कोडलैब, Android Kotlin Fundamentals कोडलैब के लैंडिंग पेज पर दिए गए हैं.
परिचय
पिछले कोडलैब में, आपने TrackMySleepQuality ऐप्लिकेशन को अपडेट किया था, ताकि RecyclerView में नींद की क्वालिटी के बारे में डेटा दिखाया जा सके. आपने अपना पहला RecyclerView बनाते समय जो तकनीकें सीखी थीं वे ज़्यादातर RecyclerViews के लिए काफ़ी हैं. ये RecyclerViews, ज़्यादा बड़ी नहीं होती हैं और इनमें सामान्य सूचियां दिखती हैं. हालांकि, ऐसी कई तकनीकें हैं जिनकी मदद से, बड़ी सूचियों के लिए RecyclerView को ज़्यादा असरदार बनाया जा सकता है. साथ ही, जटिल सूचियों और ग्रिड के लिए अपने कोड को बनाए रखना और उसे बढ़ाना आसान बनाया जा सकता है.
इस कोडलैब में, पिछले कोडलैब में बनाए गए स्लीप-ट्रैकर ऐप्लिकेशन का इस्तेमाल किया जाता है. आपको नींद से जुड़े डेटा की सूची को अपडेट करने का ज़्यादा असरदार तरीका पता चलता है. साथ ही, आपको RecyclerView के साथ डेटा बाइंडिंग का इस्तेमाल करने का तरीका पता चलता है. (अगर आपके पास पिछले कोडलैब का ऐप्लिकेशन नहीं है, तो इस कोडलैब के लिए स्टार्टर कोड डाउनलोड किया जा सकता है.)
आपको पहले से क्या पता होना चाहिए
- ऐक्टिविटी, फ़्रैगमेंट, और व्यू का इस्तेमाल करके बुनियादी यूज़र इंटरफ़ेस बनाना.
- फ़्रैगमेंट के बीच नेविगेट करना और फ़्रैगमेंट के बीच डेटा पास करने के लिए,
safeArgsका इस्तेमाल करना. - मॉडल, मॉडल फ़ैक्ट्री, ट्रांसफ़ॉर्मेशन, और
LiveDataऔर उनके ऑब्ज़र्वर देखें. Roomडेटाबेस बनाने, DAO बनाने, और इकाइयों को तय करने का तरीका.- डेटाबेस और अन्य लंबे समय तक चलने वाले टास्क के लिए, कोराउटीन का इस्तेमाल कैसे करें.
Adapter,ViewHolder, और आइटम लेआउट के साथ बुनियादीRecyclerViewको लागू करने का तरीका.
आपको क्या सीखने को मिलेगा
RecyclerViewकी ओर से दिखाई गई सूची को असरदार तरीके से अपडेट करने के लिए,DiffUtilका इस्तेमाल कैसे करें.RecyclerViewके साथ डेटा बाइंडिंग का इस्तेमाल करने का तरीका.- डेटा को बदलने के लिए, बाइंडिंग अडैप्टर का इस्तेमाल कैसे करें.
आपको क्या करना होगा
- इस सीरीज़ के पिछले कोडलैब में दिए गए TrackMySleepQuality ऐप्लिकेशन का इस्तेमाल करें.
DiffUtilका इस्तेमाल करके सूची को आसानी से अपडेट करने के लिए,SleepNightAdapterको अपडेट करें.- डेटा को बदलने के लिए, बाइंडिंग अडैप्टर का इस्तेमाल करके
RecyclerViewके लिए डेटा बाइंडिंग लागू करें.
नींद को ट्रैक करने वाले ऐप्लिकेशन में दो स्क्रीन होती हैं. इन्हें फ़्रैगमेंट के तौर पर दिखाया जाता है. इसकी जानकारी नीचे दी गई इमेज में मौजूद है.
|
|
बाईं ओर दिखाई गई पहली स्क्रीन पर, ट्रैकिंग शुरू और बंद करने के बटन हैं. स्क्रीन पर, उपयोगकर्ता की नींद से जुड़ा कुछ डेटा दिखाया गया है. मिटाएं बटन दबाने पर, ऐप्लिकेशन ने उपयोगकर्ता के लिए जो भी डेटा इकट्ठा किया है वह हमेशा के लिए मिट जाता है. दाईं ओर दिखाई गई दूसरी स्क्रीन, नींद की क्वालिटी की रेटिंग चुनने के लिए है.
इस ऐप्लिकेशन को इस तरह से डिज़ाइन किया गया है कि यह यूज़र इंटरफ़ेस (यूआई) कंट्रोलर, ViewModel, LiveData, और Room डेटाबेस का इस्तेमाल करके, नींद के डेटा को सेव कर सके.

नींद का डेटा, RecyclerView में दिखाया जाता है. इस कोडलैब में, आपको DiffUtil और RecyclerView के लिए डेटा-बाइंडिंग वाला हिस्सा बनाने का तरीका बताया गया है. इस कोडलैब के बाद, आपका ऐप्लिकेशन पहले जैसा ही दिखेगा. हालांकि, यह ज़्यादा असरदार होगा. साथ ही, इसे स्केल करना और बनाए रखना आसान होगा.
पिछले कोडलैब में इस्तेमाल किए गए SleepTracker ऐप्लिकेशन का इस्तेमाल जारी रखा जा सकता है. इसके अलावा, GitHub से RecyclerViewDiffUtilDataBinding-Starter ऐप्लिकेशन डाउनलोड किया जा सकता है.
- अगर ज़रूरत हो, तो GitHub से RecyclerViewDiffUtilDataBinding-Starter ऐप्लिकेशन डाउनलोड करें और Android Studio में प्रोजेक्ट खोलें.
- ऐप्लिकेशन चलाएं.
SleepNightAdapter.ktफ़ाइल खोलें.- ऐप्लिकेशन के स्ट्रक्चर के बारे में जानने के लिए, कोड की जांच करें. उपयोगकर्ता को नींद का डेटा दिखाने के लिए, अडैप्टर पैटर्न के साथ
RecyclerViewका इस्तेमाल करने के बारे में फिर से जानने के लिए, यहां दिया गया डायग्राम देखें.

- उपयोगकर्ता के इनपुट के आधार पर, ऐप्लिकेशन
SleepNightऑब्जेक्ट की सूची बनाता है. हरSleepNightऑब्जेक्ट, एक रात की नींद, उसकी अवधि, और क्वालिटी के बारे में बताता है. SleepNightAdapter,SleepNightऑब्जेक्ट की सूची को इस तरह से बदलता है किRecyclerViewइसका इस्तेमाल कर सके और इसे दिखा सके.SleepNightAdapterअडैप्टर,ViewHoldersबनाता है. इसमें रीसाइकलर व्यू के लिए व्यू, डेटा, और मेटा जानकारी होती है, ताकि डेटा दिखाया जा सके.RecyclerView,SleepNightAdapterका इस्तेमाल करके यह तय करता है कि कितने आइटम दिखाने हैं (getItemCount()).RecyclerView,onCreateViewHolder()औरonBindViewHolder()का इस्तेमाल करके, डेटा से जुड़े व्यू होल्डर को दिखाता है.
notifyDataSetChanged() तरीका असरदार नहीं है
RecyclerView को यह बताने के लिए कि सूची में मौजूद किसी आइटम में बदलाव हुआ है और उसे अपडेट करने की ज़रूरत है, मौजूदा कोड SleepNightAdapter में notifyDataSetChanged() को कॉल करता है. इसे यहां दिखाया गया है.
var data = listOf<SleepNight>()
set(value) {
field = value
notifyDataSetChanged()
}हालांकि, notifyDataSetChanged() से RecyclerView को पता चलता है कि पूरी सूची अमान्य हो सकती है. इस वजह से, RecyclerView सूची में मौजूद हर आइटम को फिर से बाइंड करता है और फिर से बनाता है. इसमें वे आइटम भी शामिल हैं जो स्क्रीन पर नहीं दिखते. यह बहुत ज़्यादा गै़र-ज़रूरी काम है. बड़ी या मुश्किल सूचियों के लिए, इस प्रोसेस में इतना समय लग सकता है कि उपयोगकर्ता के सूची में स्क्रोल करने पर, डिसप्ले फ़्लिकर या रुक-रुक कर चले.
इस समस्या को ठीक करने के लिए, RecyclerView को बताएं कि असल में क्या बदलाव हुआ है. इसके बाद, RecyclerView सिर्फ़ उन व्यू को अपडेट कर सकता है जो स्क्रीन पर बदले हैं.
RecyclerView में, किसी एक एलिमेंट को अपडेट करने के लिए रिच एपीआई है. RecyclerView को यह बताने के लिए कि किसी आइटम में बदलाव हुआ है, notifyItemChanged() का इस्तेमाल किया जा सकता है. साथ ही, जोड़े गए, हटाए गए या एक जगह से दूसरी जगह ले जाए गए आइटम के लिए भी इसी तरह के फ़ंक्शन का इस्तेमाल किया जा सकता है. इसे मैन्युअल तरीके से भी किया जा सकता है, लेकिन यह काम आसान नहीं होगा. इसमें काफ़ी कोड शामिल हो सकता है.
हालांकि, इससे बेहतर तरीका भी है.
DiffUtil एक असरदार टूल है और यह आपके लिए मुश्किल काम को आसान बना देता है
RecyclerView में DiffUtil नाम की एक क्लास होती है. इसका इस्तेमाल दो सूचियों के बीच अंतर का हिसाब लगाने के लिए किया जाता है. DiffUtil, पुरानी और नई सूची की तुलना करके यह पता लगाता है कि दोनों में क्या अंतर है. यह उन आइटम का पता लगाता है जिन्हें जोड़ा, हटाया या बदला गया है. इसके बाद, यह Eugene W. Myers's difference algorithm का इस्तेमाल करता है. इससे यह पता चलता है कि नई सूची बनाने के लिए, पुरानी सूची में कम से कम कितने बदलाव करने होंगे.
DiffUtil को यह पता चल जाता है कि क्या बदला है. इसके बाद, DiffUtil उस जानकारी का इस्तेमाल करके, सिर्फ़ उन आइटम को अपडेट कर सकता है जिन्हें बदला गया है, जोड़ा गया है, हटाया गया है या जिनकी जगह बदली गई है. यह पूरी सूची को फिर से बनाने से ज़्यादा असरदार है.RecyclerView
इस टास्क में, आपको SleepNightAdapter को अपग्रेड करके DiffUtil का इस्तेमाल करना है, ताकि डेटा में हुए बदलावों के लिए RecyclerView को ऑप्टिमाइज़ किया जा सके.
पहला चरण: SleepNightDiffCallback लागू करना
DiffUtil क्लास की सुविधाओं का इस्तेमाल करने के लिए, DiffUtil.ItemCallback को एक्सटेंड करें.
SleepNightAdapter.ktखोलें.SleepNightAdapterके लिए पूरी क्लास डेफ़िनिशन के नीचे,SleepNightDiffCallbackनाम की नई टॉप-लेवल क्लास बनाएं. यह क्लासDiffUtil.ItemCallbackको बढ़ाती है.SleepNightको सामान्य पैरामीटर के तौर पर पास करें.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}- कर्सर को
SleepNightDiffCallbackक्लास के नाम में रखें. Alt+Enter(Mac परOption+Enter) दबाएं और सदस्यों को लागू करें चुनें.- खुलने वाले डायलॉग बॉक्स में,
areItemsTheSame()औरareContentsTheSame()तरीकों को चुनने के लिए, Shift दबाकर बाईं ओर क्लिक करें. इसके बाद, ठीक है पर क्लिक करें.
इससे, नीचे दिखाए गए तरीके से,SleepNightDiffCallbackमें दोनों तरीकों के लिए स्टब जनरेट होते हैं.DiffUtilइन दो तरीकों का इस्तेमाल करके यह पता लगाता है कि सूची और आइटम में क्या बदलाव हुए हैं.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}areItemsTheSame()के अंदर,TODOको ऐसे कोड से बदलें जो यह जांच करता हो कि पास किए गए दोSleepNightआइटम,oldItemऔरnewItemएक जैसे हैं या नहीं. अगर आइटम काnightIdएक जैसा है, तो इसका मतलब है कि वे एक ही आइटम हैं. इसलिए,trueएट्रिब्यूट की वैल्यू के तौर पर 'हां' सेट करें. अगर ऐसा नहीं है, तोfalseदिखाएं.DiffUtilइस टेस्ट का इस्तेमाल यह पता लगाने के लिए करता है कि कोई आइटम जोड़ा गया, हटाया गया या उसे किसी दूसरी जगह ले जाया गया.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem.nightId == newItem.nightId
}areContentsTheSame()के अंदर, देखें किoldItemऔरnewItemमें एक ही डेटा है या नहीं. इसका मतलब है कि देखें कि वे बराबर हैं या नहीं. यह समानता जांच, सभी फ़ील्ड की जांच करेगी, क्योंकिSleepNightएक डेटा क्लास है.Dataक्लास, आपके लिएequalsऔर कुछ अन्य तरीकों को अपने-आप तय करती हैं. अगरoldItemऔरnewItemके बीच कोई अंतर है, तो यह कोडDiffUtilको बताता है कि आइटम अपडेट कर दिया गया है.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
return oldItem == newItem
}बदलती हुई सूची को दिखाने के लिए, RecyclerView का इस्तेमाल करना एक सामान्य पैटर्न है. RecyclerView, ListAdapter नाम की एक अडैप्टर क्लास उपलब्ध कराता है. इससे आपको एक ऐसा RecyclerView अडैप्टर बनाने में मदद मिलती है जो किसी सूची पर आधारित होता है.
ListAdapter आपके लिए सूची को ट्रैक करता है और सूची अपडेट होने पर अडैप्टर को सूचना देता है.
पहला चरण: अपने अडैप्टर को ListAdapter में बदलें
SleepNightAdapter.ktफ़ाइल में,SleepNightAdapterका क्लास सिग्नेचर बदलकरListAdapterको बढ़ाएं.- अगर कहा जाए, तो
androidx.recyclerview.widget.ListAdapterइंपोर्ट करें. SleepNightकोListAdapterफ़ंक्शन में पहले आर्ग्युमेंट के तौर पर जोड़ें. इसेSleepNightAdapter.ViewHolderसे पहले जोड़ें.- कंस्ट्रक्टर में
SleepNightDiffCallback()को पैरामीटर के तौर पर जोड़ें.ListAdapterइसका इस्तेमाल करके यह पता लगाएगा कि सूची में क्या बदलाव हुआ है. आपकी पूरी की गईSleepNightAdapterक्लास का सिग्नेचर, यहां दिखाए गए सिग्नेचर की तरह दिखना चाहिए.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {SleepNightAdapterक्लास में, सेटर के साथ-साथdataफ़ील्ड को मिटाएं. अब आपको इसकी ज़रूरत नहीं है, क्योंकिListAdapterआपके लिए लिस्ट को ट्रैक करता है.getItemCount()के ओवरराइड को मिटा दें, क्योंकिgetItemCount()आपके लिए इस तरीके को लागू करता है.ListAdapteronBindViewHolder()में मौजूद गड़बड़ी को ठीक करने के लिए,itemवैरिएबल में बदलाव करें.itemपाने के लिएdataका इस्तेमाल करने के बजाय,ListAdapterके ज़रिए उपलब्ध कराए गएgetItem(position)तरीके को कॉल करें.
val item = getItem(position)दूसरा चरण: सूची को अपडेट रखने के लिए submitList() का इस्तेमाल करना
आपके कोड को ListAdapter को यह बताना होगा कि बदली हुई सूची कब उपलब्ध है. ListAdapter, submitList() नाम का एक तरीका उपलब्ध कराता है. इससे ListAdapter को यह सूचना मिलती है कि सूची का नया वर्शन उपलब्ध है. इस तरीके को कॉल करने पर, ListAdapter नई सूची की तुलना पुरानी सूची से करता है. साथ ही, उन आइटम का पता लगाता है जिन्हें जोड़ा, हटाया, बदला या एक जगह से दूसरी जगह ले जाया गया है. इसके बाद, ListAdapter, RecyclerView पर दिखाए गए आइटम अपडेट करता है.
SleepTrackerFragment.ktखोलें.onCreateView()में,sleepTrackerViewModelपर मौजूद ऑब्ज़र्वर में, उस गड़बड़ी का पता लगाएं जिसमें आपने जिसdataवैरिएबल को मिटाया है उसका रेफ़रंस दिया गया है.adapter.data = itकोadapter.submitList(it)पर कॉल करने की सुविधा से बदलें. अपडेट किया गया कोड यहां दिया गया है.
sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.submitList(it)
}
})- ऐप्लिकेशन चलाएं. यह तेज़ी से चलता है. अगर आपकी सूची छोटी है, तो हो सकता है कि आपको यह बदलाव न दिखे.
इस टास्क में, डेटा बाइंडिंग सेट अप करने के लिए, पिछले कोडलैब में इस्तेमाल की गई तकनीक का इस्तेमाल किया जाता है. साथ ही, findViewById() को कॉल करने की सुविधा हटा दी जाती है.
पहला चरण: लेआउट फ़ाइल में डेटा बाइंडिंग जोड़ना
- टेक्स्ट टैब में जाकर,
list_item_sleep_night.xmlलेआउट फ़ाइल खोलें. - कर्सर को
ConstraintLayoutटैग पर रखें औरAlt+Enter(Mac परOption+Enter) दबाएं. इसके बाद, इंटेंट मेन्यू ("तुरंत ठीक करें" मेन्यू) खुलता है. - डेटा बाइंडिंग लेआउट में बदलें को चुनें. इससे लेआउट को
<layout>में रैप किया जाता है और इसके अंदर<data>टैग जोड़ा जाता है. - अगर ज़रूरी हो, तो वापस सबसे ऊपर जाएं. इसके बाद,
<data>टैग में,sleepनाम का वैरिएबल घोषित करें. - इसके
typeकोSleepNight,com.example.android.trackmysleepquality.database.SleepNightका पूरी तरह क्वालिफ़ाइड नाम बनाएं. आपका पूरा किया गया<data>टैग, नीचे दिए गए उदाहरण की तरह दिखना चाहिए.
<data>
<variable
name="sleep"
type="com.example.android.trackmysleepquality.database.SleepNight"/>
</data>Bindingऑब्जेक्ट को बनाने के लिए, Build > Clean Project को चुनें. इसके बाद, Build > Rebuild Project को चुनें. (अगर आपको अब भी समस्याएं आ रही हैं, तो फ़ाइल > कैश मेमोरी मिटाएं / फिर से शुरू करें चुनें.)ListItemSleepNightBindingबाइंडिंग ऑब्जेक्ट और उससे जुड़ा कोड, प्रोजेक्ट की जनरेट की गई फ़ाइलों में जोड़ दिया जाता है.
दूसरा चरण: डेटा बाइंडिंग का इस्तेमाल करके आइटम लेआउट को बड़ा करना
SleepNightAdapter.ktखोलें.ViewHolderक्लास में,from()तरीका ढूंढें.viewवैरिएबल का एलान मिटाएं.
मिटाने का कोड:
val view = layoutInflater
.inflate(R.layout.list_item_sleep_night, parent, false)viewवैरिएबल की जगह पर,bindingनाम का एक नया वैरिएबल तय करें. यहListItemSleepNightBindingबाइंडिंग ऑब्जेक्ट को बढ़ाता है. इसे नीचे दिखाया गया है. बाइंडिंग ऑब्जेक्ट को ज़रूरी तौर पर इंपोर्ट करें.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)- फ़ंक्शन के आखिर में,
viewदिखाने के बजायbindingदिखाएं.
return ViewHolder(binding)- गड़बड़ी को ठीक करने के लिए, अपने कर्सर को
bindingशब्द पर रखें. इंटेंशन मेन्यू खोलने के लिए,Alt+Enter(Mac परOption+Enter) दबाएं.
- क्लास 'ViewHolder' के मुख्य कंस्ट्रक्टर के पैरामीटर 'itemView' के टाइप को 'ListItemSleepNightBinding' में बदलें को चुनें. इससे
ViewHolderक्लास के पैरामीटर टाइप को अपडेट किया जाता है.

- हस्ताक्षर में हुए बदलाव को देखने के लिए,
ViewHolderकी क्लास डेफ़िनिशन तक ऊपर की ओर स्क्रोल करें. आपकोitemViewके लिए गड़बड़ी दिख रही है, क्योंकि आपनेfrom()तरीके मेंitemViewकोbindingमें बदल दिया है.ViewHolderक्लास की परिभाषा में,itemViewके किसी एक उदाहरण पर राइट क्लिक करें. इसके बाद, रीफ़ैक्टर करें > नाम बदलें को चुनें. नाम बदलकरbindingकर दें. - कंस्ट्रक्टर पैरामीटर
bindingको प्रॉपर्टी बनाने के लिए, इसके पहलेvalजोड़ें. - पैरंट क्लास
RecyclerView.ViewHolderको कॉल करते समय, पैरामीटर कोbindingसे बदलकरbinding.rootकरें. आपकोViewपास करना होगा. साथ ही,binding.rootआपके आइटम लेआउट में रूटConstraintLayoutहै. - क्लास का एलान करने के बाद, आपका कोड यहां दिए गए कोड जैसा दिखना चाहिए.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){आपको findViewById() पर किए गए कॉल के लिए भी गड़बड़ी दिखती है. इसे ठीक करने के लिए, यह तरीका आज़माएं.
तीसरा चरण: findViewById() को बदलें
अब findViewById() के बजाय binding ऑब्जेक्ट का इस्तेमाल करने के लिए, sleepLength, quality, और qualityImage प्रॉपर्टी अपडेट की जा सकती हैं.
sleepLength,qualityString, औरqualityImageके इनिशियलाइज़ेशन को बदलकर,bindingऑब्जेक्ट के व्यू का इस्तेमाल करें. इसके लिए, यहां दिया गया तरीका अपनाएं. इसके बाद, आपके कोड में कोई और गड़बड़ी नहीं दिखनी चाहिए.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImageबाइंडिंग ऑब्जेक्ट का इस्तेमाल करने पर, आपको sleepLength, quality, और qualityImage प्रॉपर्टी को अब तय करने की ज़रूरत नहीं है. DataBinding लुकअप को कैश मेमोरी में सेव करेगा. इसलिए, इन प्रॉपर्टी को घोषित करने की ज़रूरत नहीं है.
sleepLength,quality, औरqualityImageप्रॉपर्टी के नामों पर राइट क्लिक करें. Refactor > Inline चुनें याControl+Command+N(Mac परOption+Command+N) दबाएं.
- अपना ऐप्लिकेशन चलाएं. अगर आपके प्रोजेक्ट में गड़बड़ियां हैं, तो आपको उसे क्लीन और फिर से बनाना पड़ सकता है.
इस टास्क में, आपको अपने ऐप्लिकेशन को अपग्रेड करना है, ताकि वह डेटा बाइंडिंग और बाइंडिंग अडैप्टर का इस्तेमाल करके, व्यू में डेटा सेट कर सके.
पिछले कोडलैब में, आपने Transformations क्लास का इस्तेमाल करके LiveData लिया था. साथ ही, टेक्स्ट व्यू में दिखाने के लिए फ़ॉर्मैट की गई स्ट्रिंग जनरेट की थीं. हालांकि, अगर आपको अलग-अलग टाइप या जटिल टाइप बाइंड करने हैं, तो बाइंडिंग अडैप्टर दिए जा सकते हैं. इससे डेटा बाइंडिंग को उन टाइप का इस्तेमाल करने में मदद मिलती है. बाइंडिंग अडैप्टर ऐसे अडैप्टर होते हैं जो आपके डेटा को लेते हैं और उसे ऐसे फ़ॉर्मैट में बदलते हैं जिसका इस्तेमाल डेटा बाइंडिंग, व्यू को बाइंड करने के लिए कर सकती है. जैसे, टेक्स्ट या इमेज.
आपको तीन बाइंडिंग अडैप्टर लागू करने हैं. इनमें से एक अडैप्टर क्वालिटी इमेज के लिए और एक-एक अडैप्टर हर टेक्स्ट फ़ील्ड के लिए होगा. संक्षेप में, बाइंडिंग अडैप्टर को तय करने के लिए, एक ऐसा तरीका तय करें जो किसी आइटम और व्यू को लेता हो. साथ ही, उसे @BindingAdapter के साथ एनोटेट करें. तरीके के मुख्य हिस्से में, ट्रांसफ़ॉर्मेशन लागू किया जाता है. Kotlin में, डेटा पाने वाली व्यू क्लास पर एक्सटेंशन फ़ंक्शन के तौर पर बाइंडिंग अडैप्टर लिखा जा सकता है.
पहला चरण: बाइंडिंग अडैप्टर बनाना
ध्यान दें कि आपको इस चरण में कई क्लास इंपोर्ट करनी होंगी. इन्हें अलग-अलग नहीं दिखाया जाएगा.
SleepNightAdapater.ktखोलें.ViewHolderक्लास में,bind()तरीका ढूंढें और याद करें कि यह तरीका क्या करता है. आपकोbinding.sleepLength,binding.quality, औरbinding.qualityImageकी वैल्यू का हिसाब लगाने वाले कोड को लेना होगा. इसके बाद, इसे अडैप्टर के अंदर इस्तेमाल करना होगा. (अभी के लिए, कोड को ऐसे ही रहने दें. इसे बाद में बदला जाएगा.)sleeptrackerपैकेज में,BindingUtils.ktनाम की फ़ाइल बनाएं और उसे खोलें.TextViewपरsetSleepDurationFormattedनाम के एक्सटेंशन फ़ंक्शन का एलान करें और उसमेंSleepNightपास करें. यह फ़ंक्शन, नींद की अवधि का हिसाब लगाने और उसे फ़ॉर्मैट करने के लिए आपके अडैप्टर के तौर पर काम करेगा.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}setSleepDurationFormattedके मुख्य हिस्से में, डेटा को व्यू से उसी तरह बाइंड करें जिस तरह आपनेViewHolder.bind()में किया था.convertDurationToFormatted()को कॉल करें. इसके बाद,TextViewकेtextको फ़ॉर्मैट किए गए टेक्स्ट पर सेट करें. (यहTextViewपर एक एक्सटेंशन फ़ंक्शन है. इसलिए,textप्रॉपर्टी को सीधे तौर पर ऐक्सेस किया जा सकता है.)
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)- डेटा बाइंडिंग को इस बाइंडिंग अडैप्टर के बारे में बताने के लिए, फ़ंक्शन को
@BindingAdapterके साथ एनोटेट करें. - यह फ़ंक्शन,
sleepDurationFormattedएट्रिब्यूट के लिए अडैप्टर है. इसलिए,@BindingAdapterको@BindingAdapterके लिए आर्ग्युमेंट के तौर पर पास करें.sleepDurationFormatted
@BindingAdapter("sleepDurationFormatted")- दूसरा अडैप्टर,
SleepNightऑब्जेक्ट में मौजूद वैल्यू के आधार पर नींद की क्वालिटी सेट करता है.TextViewपरsetSleepQualityString()नाम का एक्सटेंशन फ़ंक्शन बनाएं और उसमेंSleepNightपास करें. - बॉडी में, डेटा को व्यू से उसी तरह बाइंड करें जिस तरह आपने
ViewHolder.bind()में किया था.convertNumericQualityToStringको कॉल करो औरtextसेट करो. - फ़ंक्शन को
@BindingAdapter("sleepQualityString")से एनोटेट करें.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
text = convertNumericQualityToString(item.sleepQuality, context.resources)
}- तीसरा बाइंडिंग अडैप्टर, इमेज व्यू पर इमेज सेट करता है. नीचे दिए गए तरीके से,
ImageViewपर एक्सटेंशन फ़ंक्शन बनाएं,setSleepImageको कॉल करें, औरViewHolder.bind()से कोड का इस्तेमाल करें.
@BindingAdapter("sleepImage")
fun ImageView.setSleepImage(item: SleepNight) {
setImageResource(when (item.sleepQuality) {
0 -> R.drawable.ic_sleep_0
1 -> R.drawable.ic_sleep_1
2 -> R.drawable.ic_sleep_2
3 -> R.drawable.ic_sleep_3
4 -> R.drawable.ic_sleep_4
5 -> R.drawable.ic_sleep_5
else -> R.drawable.ic_sleep_active
})
}दूसरा चरण: SleepNightAdapter को अपडेट करना
SleepNightAdapter.ktखोलें.bind()तरीके में मौजूद हर चीज़ को मिटा दें, क्योंकि अब डेटा बाइंडिंग और नए अडैप्टर का इस्तेमाल करके, यह काम किया जा सकता है.
fun bind(item: SleepNight) {
}bind()के अंदर,itemको स्लीप असाइन करें, क्योंकि आपको बाइंडिंग ऑब्जेक्ट को अपने नएSleepNightके बारे में बताना है.
binding.sleep = item- उस लाइन के नीचे,
binding.executePendingBindings()जोड़ें. यह कॉल एक ऑप्टिमाइज़ेशन है, जो डेटा बाइंडिंग से तुरंत सभी लंबित बाइंडिंग को लागू करने के लिए कहता है.RecyclerViewमें बाइंडिंग अडैप्टर का इस्तेमाल करते समय,executePendingBindings()को कॉल करना हमेशा अच्छा होता है. इससे व्यू का साइज़ तय करने में थोड़ी तेज़ी आ सकती है.
binding.executePendingBindings()तीसरा चरण: एक्सएमएल लेआउट में बाइंडिंग जोड़ना
list_item_sleep_night.xmlखोलें.ImageViewमें,appप्रॉपर्टी जोड़ें. इसका नाम, इमेज सेट करने वाले बाइंडिंग अडैप्टर के नाम जैसा होना चाहिए. नीचे दिखाए गए तरीके से,sleepवैरिएबल पास करें.
यह प्रॉपर्टी, अडैप्टर के ज़रिए व्यू और बाइंडिंग ऑब्जेक्ट के बीच कनेक्शन बनाती है. जब भीsleepImageका रेफ़रंस दिया जाता है, तब अडैप्टर,SleepNightसे डेटा को अडैप्ट कर लेता है.
app:sleepImage="@{sleep}"sleep_lengthऔरquality_stringटेक्स्ट व्यू के लिए भी ऐसा ही करें. जब भीsleepDurationFormattedयाsleepQualityStringका रेफ़रंस दिया जाता है, तब अडैप्टर,SleepNightसे डेटा को अडैप्ट कर लेंगे.
app:sleepDurationFormatted="@{sleep}"app:sleepQualityString="@{sleep}"- अपना ऐप्लिकेशन चलाएं. यह ठीक उसी तरह काम करता है जैसे पहले करता था. डेटा में बदलाव होने पर, बाइंडिंग अडैप्टर व्यू को फ़ॉर्मैट करने और अपडेट करने का काम करते हैं. इससे
ViewHolderआसान हो जाता है. साथ ही, कोड को पहले से बेहतर स्ट्रक्चर मिलता है.
आपने पिछली कुछ कसरतों के लिए एक ही सूची दिखाई है. ऐसा इसलिए किया गया है, ताकि आपको यह दिखाया जा सके कि Adapter इंटरफ़ेस की मदद से, कोड को कई अलग-अलग तरीकों से बनाया जा सकता है. आपका कोड जितना जटिल होगा, उसे अच्छी तरह से डिज़ाइन करना उतना ही ज़रूरी होगा. प्रोडक्शन ऐप्लिकेशन में, इन पैटर्न और अन्य पैटर्न का इस्तेमाल RecyclerView के साथ किया जाता है. ये सभी पैटर्न काम करते हैं और हर पैटर्न के अपने फ़ायदे हैं. आपको कौनसा विकल्प चुनना है, यह इस बात पर निर्भर करता है कि आपको क्या बनाना है.
बधाई हो! अब तक, आपने Android पर RecyclerView का इस्तेमाल करना सीख लिया होगा.
Android Studio प्रोजेक्ट: RecyclerViewDiffUtilDataBinding.
DiffUtil:
RecyclerViewमेंDiffUtilनाम की एक क्लास होती है. इसका इस्तेमाल दो सूचियों के बीच अंतर का हिसाब लगाने के लिए किया जाता है.DiffUtilमेंItemCallBackनाम की एक क्लास है. दो सूचियों के बीच का अंतर पता लगाने के लिए, आपको इस क्लास को बढ़ाना होगा.ItemCallbackक्लास में, आपकोareItemsTheSame()औरareContentsTheSame()तरीकों को ओवरराइड करना होगा.
ListAdapter:
- सूची को मैनेज करने की कुछ सुविधाएं बिना किसी शुल्क के पाने के लिए,
RecyclerView.Adapterके बजायListAdapterक्लास का इस्तेमाल करें. हालांकि, अगरListAdapterका इस्तेमाल किया जाता है, तो आपको अन्य लेआउट के लिए अपना अडैप्टर लिखना होगा. इसलिए, यह कोडलैब आपको ऐसा करने का तरीका दिखाता है. - Android Studio में इंटेंशन मेन्यू खोलने के लिए, कर्सर को कोड के किसी भी आइटम पर रखें और
Alt+Enter(Mac परOption+Enter) दबाएं. यह मेन्यू, कोड को फिर से व्यवस्थित करने और तरीकों को लागू करने के लिए स्टब बनाने में खास तौर पर मददगार होता है. यह मेन्यू, कॉन्टेक्स्ट के हिसाब से काम करता है. इसलिए, सही मेन्यू पाने के लिए आपको कर्सर को सही जगह पर रखना होगा.
डेटा बाइंडिंग:
- आइटम लेआउट में डेटा बाइंडिंग का इस्तेमाल करके, डेटा को व्यू से बाइंड करें.
बाइंडिंग अडैप्टर:
- आपने पहले
Transformationsका इस्तेमाल करके, डेटा से स्ट्रिंग बनाई थीं. अगर आपको अलग-अलग या जटिल टाइप के डेटा को बाइंड करना है, तो बाइंडिंग अडैप्टर उपलब्ध कराएं. इससे डेटा बाइंडिंग को उनका इस्तेमाल करने में मदद मिलेगी. - बाइंडिंग अडैप्टर को तय करने के लिए, एक ऐसा तरीका तय करें जो आइटम और व्यू लेता हो. साथ ही, इस तरीके को
@BindingAdapterसे एनोटेट करें. Kotlin में, बाइंडिंग अडैप्टर कोViewपर एक्सटेंशन फ़ंक्शन के तौर पर लिखा जा सकता है. उस प्रॉपर्टी का नाम पास करें जिसे अडैप्टर अडैप्ट करता है. उदाहरण के लिए:
@BindingAdapter("sleepDurationFormatted")- एक्सएमएल लेआउट में, बाइंडिंग अडैप्टर के नाम वाली
appप्रॉपर्टी सेट करें. डेटा के साथ वैरिएबल पास करें. उदाहरण के लिए:
.app:sleepDurationFormatted="@{sleep}"Udacity के कोर्स:
Android डेवलपर का दस्तावेज़:
- RecyclerView की मदद से सूची बनाना
RecyclerViewDiffUtil- डेटा बाइंडिंग लाइब्रेरी
- बाइंडिंग अडैप्टर
notifyDataSetChanged()Transformations
अन्य संसाधन:
इस सेक्शन में, उन छात्र-छात्राओं के लिए होमवर्क असाइनमेंट की सूची दी गई है जो किसी शिक्षक के कोर्स के हिस्से के तौर पर इस कोडलैब पर काम कर रहे हैं. शिक्षक के पास ये विकल्प होते हैं:
- अगर ज़रूरी हो, तो होमवर्क असाइन करें.
- छात्र-छात्राओं को बताएं कि होमवर्क असाइनमेंट कैसे सबमिट किए जाते हैं.
- होमवर्क असाइनमेंट को ग्रेड दें.
शिक्षक इन सुझावों का इस्तेमाल अपनी ज़रूरत के हिसाब से कर सकते हैं. साथ ही, वे चाहें, तो कोई दूसरा होमवर्क भी दे सकते हैं.
अगर आपको यह कोडलैब खुद से पूरा करना है, तो अपनी जानकारी की जांच करने के लिए, इन होमवर्क असाइनमेंट का इस्तेमाल करें.
इन सवालों के जवाब दें
पहला सवाल
DiffUtil का इस्तेमाल करने के लिए, इनमें से कौनसी चीज़ें ज़रूरी हैं? लागू होने वाले सभी विकल्पों को चुनें.
▢ ItemCallBack क्लास को बढ़ाएं.
▢ बदलें areItemsTheSame().
▢ बदलें areContentsTheSame().
▢ सामानों के बीच अंतर को ट्रैक करने के लिए, डेटा बाइंडिंग का इस्तेमाल करें.
सवाल 2
बाइंडिंग अडैप्टर के बारे में इनमें से कौनसी बातें सही हैं?
▢ बाइंडिंग अडैप्टर, @BindingAdapter एनोटेशन वाला फ़ंक्शन होता है.
▢ बाइंडिंग अडैप्टर का इस्तेमाल करके, डेटा फ़ॉर्मैटिंग को व्यू होल्डर से अलग किया जा सकता है.
▢ अगर आपको बाइंडिंग अडैप्टर का इस्तेमाल करना है, तो आपको RecyclerViewAdapter का इस्तेमाल करना होगा.
▢ जब आपको मुश्किल डेटा को बदलना हो, तब बाइंडिंग अडैप्टर एक अच्छा विकल्प है.
सवाल 3
आपको बाइंडिंग अडैप्टर के बजाय Transformations का इस्तेमाल कब करना चाहिए? लागू होने वाले सभी विकल्पों को चुनें.
▢ आपका डेटा सामान्य है.
▢ स्ट्रिंग को फ़ॉर्मैट किया जा रहा है.
▢ आपकी सूची बहुत लंबी है.
▢ आपके ViewHolder में सिर्फ़ एक व्यू शामिल है.
अगला लेसन शुरू करें:

