यह कोडलैब, Kotlin में ऐडवांस Android कोर्स का हिस्सा है. अगर इस कोर्स के कोडलैब को क्रम से पूरा किया जाता है, तो आपको सबसे ज़्यादा फ़ायदा मिलेगा. हालांकि, ऐसा करना ज़रूरी नहीं है. कोर्स के सभी कोडलब, Advanced Android in Kotlin कोडलब के लैंडिंग पेज पर दिए गए हैं.
परिचय
Android, View
की कई सबक्लास उपलब्ध कराता है. जैसे, Button
, TextView
, EditText
, ImageView
, CheckBox
या RadioButton
. इन सबक्लास का इस्तेमाल करके, ऐसा यूज़र इंटरफ़ेस (यूआई) बनाया जा सकता है जिससे उपयोगकर्ता इंटरैक्ट कर सकें और आपके ऐप्लिकेशन में जानकारी दिख सके. अगर इनमें से कोई भी View
सबक्लास आपकी ज़रूरतों को पूरा नहीं करती है, तो View
सबक्लास बनाई जा सकती है. इसे कस्टम व्यू कहा जाता है.
कस्टम व्यू बनाने के लिए, मौजूदा View
सबक्लास (जैसे कि Button
या EditText
) को बढ़ाया जा सकता है. इसके अलावा, View
की अपनी सबक्लास बनाई जा सकती है. View
को सीधे तौर पर बढ़ाकर, किसी भी साइज़ और शेप का इंटरैक्टिव यूज़र इंटरफ़ेस (यूआई) एलिमेंट बनाया जा सकता है. इसके लिए, View
को ड्रॉ करने के लिए onDraw()
तरीके को बदलें.
कस्टम व्यू बनाने के बाद, उसे अपनी गतिविधि के लेआउट में जोड़ा जा सकता है. इसे उसी तरह जोड़ा जाता है जिस तरह TextView
या Button
को जोड़ा जाता है.
इस लेख में, View
को बढ़ाकर, कस्टम व्यू बनाने का तरीका बताया गया है.
आपको पहले से क्या पता होना चाहिए
- Android Studio का इस्तेमाल करके, गतिविधि वाला ऐप्लिकेशन बनाने और उसे चलाने का तरीका.
आपको क्या सीखने को मिलेगा
- कस्टम व्यू बनाने के लिए,
View
को बढ़ाने का तरीका. - सर्कुलर शेप में कस्टम व्यू बनाने का तरीका.
- कस्टम व्यू के साथ उपयोगकर्ता के इंटरैक्शन को मैनेज करने के लिए, लिसनर का इस्तेमाल करने का तरीका.
- लेआउट में कस्टम व्यू का इस्तेमाल कैसे करें.
आपको क्या करना होगा
CustomFanController ऐप्लिकेशन, View
क्लास को बढ़ाकर कस्टम व्यू सबक्लास बनाने का तरीका दिखाता है. नई सबक्लास को DialView
कहा जाता है.
ऐप्लिकेशन में, गोल आकार का यूज़र इंटरफ़ेस (यूआई) एलिमेंट दिखता है. यह फ़ैन को कंट्रोल करने वाले फ़िज़िकल बटन जैसा दिखता है. इसमें फ़ैन को बंद करने (0), कम (1), मीडियम (2), और तेज़ (3) पर चलाने की सेटिंग होती है. जब उपयोगकर्ता व्यू पर टैप करता है, तो चुनने का इंडिकेटर अगली पोज़िशन पर चला जाता है: 0-1-2-3 और फिर वापस 0 पर आ जाता है. इसके अलावा, अगर पंखे की स्पीड 1 या इससे ज़्यादा पर सेट है, तो व्यू के गोलाकार हिस्से का बैकग्राउंड रंग स्लेटी से हरा हो जाता है. इससे पता चलता है कि पंखा चालू है.
व्यू, किसी ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) के बुनियादी बिल्डिंग ब्लॉक होते हैं. View
क्लास कई सबक्लास उपलब्ध कराता है. इन्हें यूज़र इंटरफ़ेस (यूआई) विजेट कहा जाता है. ये Android ऐप्लिकेशन के यूज़र इंटरफ़ेस की कई ज़रूरतों को पूरा करते हैं.
यूज़र इंटरफ़ेस (यूआई) के बिल्डिंग ब्लॉक, जैसे कि Button
और TextView
, ऐसी सबक्लास हैं जो View
क्लास को बढ़ाती हैं. समय और डेवलपमेंट की मेहनत बचाने के लिए, इनमें से किसी एक View
सबक्लास को बढ़ाया जा सकता है. कस्टम व्यू, अपने पैरंट व्यू के लुक और व्यवहार को इनहेरिट करता है. हालांकि, आपके पास लुक या व्यवहार के उस पहलू को बदलने का विकल्प होता है जिसे आपको बदलना है. उदाहरण के लिए, अगर कस्टम व्यू बनाने के लिए EditText
को बढ़ाया जाता है, तो व्यू, EditText
व्यू की तरह ही काम करता है. हालांकि, इसे इस तरह से भी पसंद के मुताबिक बनाया जा सकता है कि यह, उदाहरण के लिए, X बटन दिखाए. यह बटन, टेक्स्ट एंट्री फ़ील्ड से टेक्स्ट मिटाता है.
अपनी पसंद के मुताबिक व्यू पाने के लिए, किसी भी View
सबक्लास, जैसे कि EditText
को बढ़ाया जा सकता है. वह सबक्लास चुनें जो आपके काम के सबसे ज़्यादा करीब हो. इसके बाद, कस्टम व्यू का इस्तेमाल एक या उससे ज़्यादा लेआउट में, किसी अन्य View
सबक्लास की तरह किया जा सकता है. इसके लिए, इसे एट्रिब्यूट वाले एक्सएमएल एलिमेंट के तौर पर इस्तेमाल करें.
शुरुआत से अपना कस्टम व्यू बनाने के लिए, View
क्लास को बढ़ाएं. आपका कोड, व्यू की परफ़ॉर्मेंस और काम करने के तरीके को तय करने के लिए, View
तरीकों को बदल देता है. कस्टम व्यू बनाने के लिए, यह ज़रूरी है कि आप स्क्रीन पर किसी भी साइज़ और शेप के पूरे यूज़र इंटरफ़ेस (यूआई) एलिमेंट को ड्रॉ करें. अगर किसी मौजूदा व्यू, जैसे कि Button
को सबक्लास किया जाता है, तो वह क्लास आपके लिए ड्रॉइंग को मैनेज करती है. (आपको इस कोडलैब में बाद में ड्राइंग के बारे में ज़्यादा जानकारी मिलेगी.)
कस्टम व्यू बनाने के लिए, यह सामान्य तरीका अपनाएं:
View
को बढ़ाने वाली कस्टम व्यू क्लास बनाएं याView
की सबक्लास (जैसे किButton
याEditText
) को बढ़ाएं.- अगर आपको किसी मौजूदा
View
सबक्लास को बढ़ाना है, तो सिर्फ़ उस व्यवहार या दिखने के तरीके को बदलें जिसे आपको बदलना है. - अगर आपको
View
क्लास को बढ़ाना है, तो कस्टम व्यू का आकार बनाएं. साथ ही, नई क्लास मेंView
केonDraw()
औरonMeasure()
जैसे तरीकों को बदलकर, कस्टम व्यू की स्टाइल को कंट्रोल करें. - उपयोगकर्ता के इंटरैक्शन का जवाब देने के लिए कोड जोड़ें. साथ ही, अगर ज़रूरी हो, तो कस्टम व्यू को फिर से बनाएं.
- अपनी ऐक्टिविटी के एक्सएमएल लेआउट में, कस्टम व्यू क्लास को यूज़र इंटरफ़ेस (यूआई) विजेट के तौर पर इस्तेमाल करें. अलग-अलग लेआउट में व्यू को पसंद के मुताबिक बनाने के लिए, व्यू के लिए कस्टम एट्रिब्यूट भी तय किए जा सकते हैं.
इस टास्क में आपको:
- कस्टम व्यू के लिए,
ImageView
को कुछ समय के लिए प्लेसहोल्डर के तौर पर इस्तेमाल करके कोई ऐप्लिकेशन बनाएं. - कस्टम व्यू बनाने के लिए,
View
को बड़ा करें. - ड्रॉइंग और पेंटिंग की वैल्यू के साथ कस्टम व्यू को शुरू करें.
पहला चरण: ImageView प्लेसहोल्डर वाला ऐप्लिकेशन बनाना
- Empty Activity टेंप्लेट का इस्तेमाल करके,
CustomFanController
टाइटल वाला Kotlin ऐप्लिकेशन बनाएं. पक्का करें कि पैकेज का नामcom.example.android.customfancontroller
हो. - एक्सएमएल कोड में बदलाव करने के लिए, टेक्स्ट टैब में
activity_main.xml
खोलें. - मौजूदा
TextView
को इस कोड से बदलें. यह टेक्स्ट, कस्टम व्यू के लिए गतिविधि में लेबल के तौर पर काम करता है.
<TextView
android:id="@+id/customViewLabel"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Display3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:textColor="@android:color/black"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="24dp"
android:text="Fan Control"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
- इस
ImageView
एलिमेंट को लेआउट में जोड़ें. यह उस कस्टम व्यू के लिए प्लेसहोल्डर है जिसे आपको इस कोडलैब में बनाना है.
<ImageView
android:id="@+id/dialView"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@android:color/darker_gray"
app:layout_constraintTop_toBottomOf="@+id/customViewLabel"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"/>
- दोनों यूज़र इंटरफ़ेस (यूआई) एलिमेंट में स्ट्रिंग और डाइमेंशन रिसॉर्स एक्सट्रैक्ट करें.
- डिज़ाइन टैब पर क्लिक करें. लेआउट ऐसा दिखना चाहिए:
दूसरा चरण. कस्टम व्यू क्लास बनाना
DialView
नाम की नई Kotlin क्लास बनाएं.View
को बढ़ाने के लिए, क्लास की परिभाषा में बदलाव करें. निर्देश मिलने पर,android.view.View
इंपोर्ट करें.View
पर क्लिक करें. इसके बाद, लाल रंग के बल्ब पर क्लिक करें. '@JvmOverloads' का इस्तेमाल करके, Android व्यू कंस्ट्रक्टर जोड़ें को चुनें. Android Studio,View
क्लास से कंस्ट्रक्टर जोड़ता है.@JvmOverloads
एनोटेशन, Kotlin कंपाइलर को इस फ़ंक्शन के लिए ओवरलोड जनरेट करने का निर्देश देता है. ये ओवरलोड, डिफ़ॉल्ट पैरामीटर वैल्यू को बदल देते हैं.
class DialView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
DialView
क्लास की परिभाषा के ऊपर, इंपोर्ट के ठीक नीचे, उपलब्ध पंखे की स्पीड दिखाने के लिए टॉप-लेवलenum
जोड़ें. ध्यान दें कि यहenum
,Int
टाइप का है, क्योंकि वैल्यू असल स्ट्रिंग के बजाय स्ट्रिंग रिसॉर्स हैं. Android Studio, इन वैल्यू में मौजूद स्ट्रिंग रिसॉर्स के लिए गड़बड़ियां दिखाएगा. हालांकि, आपको बाद के चरण में इन्हें ठीक करना होगा.
private enum class FanSpeed(val label: Int) {
OFF(R.string.fan_off),
LOW(R.string.fan_low),
MEDIUM(R.string.fan_medium),
HIGH(R.string.fan_high);
}
enum
के नीचे, ये कॉन्सटेंट जोड़ें. इनका इस्तेमाल, डायल इंडिकेटर और लेबल बनाने के लिए किया जाएगा.
private const val RADIUS_OFFSET_LABEL = 30
private const val RADIUS_OFFSET_INDICATOR = -35
DialView
क्लास में, कस्टम व्यू बनाने के लिए ज़रूरी वैरिएबल तय करें. अगर कहा जाए, तोandroid.graphics.PointF
इंपोर्ट करें.
private var radius = 0.0f // Radius of the circle.
private var fanSpeed = FanSpeed.OFF // The active selection.
// position variable which will be used to draw label and indicator circle position
private val pointPosition: PointF = PointF(0.0f, 0.0f)
radius
, सर्कल का मौजूदा दायरा है. यह वैल्यू तब सेट होती है, जब व्यू को स्क्रीन पर दिखाया जाता है.fanSpeed
पंखे की मौजूदा स्पीड है. यहFanSpeed
इन्यूमरेशन में मौजूद वैल्यू में से एक है. डिफ़ॉल्ट रूप से, यह वैल्यूOFF
होती है.- Finally
postPosition
एक X,Y पॉइंट है. इसका इस्तेमाल, स्क्रीन पर व्यू के कई एलिमेंट बनाने के लिए किया जाएगा.
इन वैल्यू को व्यू के रेंडर होने के समय के बजाय, यहां बनाया और शुरू किया जाता है. इससे यह पक्का किया जा सकता है कि रेंडरिंग का प्रोसेस तेज़ी से हो.
- साथ ही,
DialView
क्लास की परिभाषा में, कुछ बुनियादी स्टाइल के साथPaint
ऑब्जेक्ट को शुरू करें. अनुरोध किए जाने पर,android.graphics.Paint
औरandroid.graphics.Typeface
इंपोर्ट करें. पहले की तरह, यहां वैरिएबल के साथ-साथ इन स्टाइल को भी शुरू किया गया है, ताकि ड्रॉइंग की प्रोसेस को तेज़ी से पूरा किया जा सके.
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
style = Paint.Style.FILL
textAlign = Paint.Align.CENTER
textSize = 55.0f
typeface = Typeface.create( "", Typeface.BOLD)
}
res/values/strings.xml
खोलें और पंखे की स्पीड के लिए स्ट्रिंग रिसॉर्स जोड़ें:
<string name="fan_off">off</string>
<string name="fan_low">1</string>
<string name="fan_medium">2</string>
<string name="fan_high">3</string>
कस्टम व्यू बनाने के बाद, आपको उसे ड्रा करने की सुविधा मिलनी चाहिए. जब किसी View
सबक्लास, जैसे कि EditText
को बढ़ाया जाता है, तो वह सबक्लास व्यू की बनावट और एट्रिब्यूट तय करता है. साथ ही, स्क्रीन पर खुद को दिखाता है. इसलिए, आपको व्यू बनाने के लिए कोड लिखने की ज़रूरत नहीं होती. इसके बजाय, अपने व्यू को पसंद के मुताबिक बनाने के लिए, पैरंट के तरीकों को बदला जा सकता है.
अगर आपको स्क्रैच से अपना व्यू बनाना है (View
को बढ़ाकर), तो स्क्रीन के रीफ़्रेश होने पर, पूरे व्यू को हर बार ड्रॉ करने की ज़िम्मेदारी आपकी होगी. साथ ही, ड्रॉ करने वाली View
के तरीकों को बदलने की ज़िम्मेदारी भी आपकी होगी. View
तक फैले कस्टम व्यू को सही तरीके से बनाने के लिए, आपको ये काम करने होंगे:
onSizeChanged()
तरीके को बदलकर, व्यू के पहली बार दिखने पर उसके साइज़ का हिसाब लगाएं. साथ ही, व्यू के साइज़ में बदलाव होने पर भी ऐसा करें.onDraw()
तरीके को बदलकर, कस्टम व्यू बनाएं. इसके लिए,Paint
ऑब्जेक्ट से स्टाइल किए गएCanvas
ऑब्जेक्ट का इस्तेमाल करें.- जब उपयोगकर्ता के क्लिक करने पर व्यू में बदलाव होता है, तब
invalidate()
तरीके को कॉल करें. इससे पूरे व्यू को अमान्य कर दिया जाता है. इस वजह से, व्यू को फिर से बनाने के लिएonDraw()
को कॉल करना पड़ता है.
onDraw()
तरीके को हर बार स्क्रीन रीफ़्रेश होने पर कॉल किया जाता है. ऐसा एक सेकंड में कई बार हो सकता है. परफ़ॉर्मेंस को बेहतर बनाने और विज़ुअल गड़बड़ियों से बचने के लिए, आपको onDraw()
में कम से कम काम करना चाहिए. खास तौर पर, onDraw()
में मेमोरी असाइन न करें. ऐसा इसलिए, क्योंकि मेमोरी असाइन करने से गार्बेज कलेक्शन हो सकता है. इससे विज़ुअल स्टटरिंग की समस्या हो सकती है.
Canvas
और Paint
क्लास में, ड्राइंग के कई काम के शॉर्टकट उपलब्ध होते हैं:
drawText()
का इस्तेमाल करके टेक्स्ट बनाएं.setTypeface()
को कॉल करके टाइपफ़ेस औरsetColor()
को कॉल करके टेक्स्ट का रंग तय करें.drawRect()
,drawOval()
, औरdrawArc()
का इस्तेमाल करके, सामान्य आकृतियां बनाएं.setStyle()
को कॉल करके, यह बदलें कि शेप में रंग भरा गया है, आउटलाइन बनाई गई है या दोनों काम किए गए हैं.drawBitmap()
का इस्तेमाल करके बिटमैप बनाएं.
आपको बाद के कोडलैब में Canvas
और Paint
के बारे में ज़्यादा जानकारी मिलेगी. Android, व्यू को कैसे ड्रॉ करता है, इस बारे में ज़्यादा जानने के लिए Android, व्यू को कैसे ड्रॉ करता है लेख पढ़ें.
इस टास्क में, आपको onSizeChanged()
और onDraw()
तरीकों का इस्तेमाल करके, स्क्रीन पर फ़ैन कंट्रोलर का कस्टम व्यू बनाना होगा. इसमें डायल, मौजूदा पोज़िशन इंडिकेटर, और इंडिकेटर लेबल शामिल हैं. आपको एक हेल्पर मेथड, computeXYForSpeed(),
भी बनाना होगा. इससे डायल पर इंडिकेटर लेबल की मौजूदा X,Y पोज़िशन का हिसाब लगाया जा सकेगा.
पहला चरण. पोजीशन कैलकुलेट करना और व्यू बनाना
- कस्टम व्यू के डायल का साइज़ कैलकुलेट करने के लिए,
DialView
क्लास में, इनिशियलाइज़ेशन के नीचे,View
क्लास सेonSizeChanged()
तरीके को बदलें.kotlin
को इंपोर्ट करें.math.min
का अनुरोध करने पर.
लेआउट के बड़ा होने पर,onSizeChanged()
तरीके को तब कॉल किया जाता है, जब व्यू का साइज़ बदलता है. इसमें पहली बार व्यू के ड्रॉ होने का समय भी शामिल है.onSizeChanged()
को ओवरराइड करके, अपनी कस्टम व्यू की साइज़ से जुड़ी पोज़िशन, डाइमेंशन, और अन्य वैल्यू कैलकुलेट करें. ऐसा हर बार ड्रॉ करने के बजाय करें. इस मामले में, डायल के सर्कल एलिमेंट के मौजूदा रेडियस का हिसाब लगाने के लिएonSizeChanged()
का इस्तेमाल किया जाता है.
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
radius = (min(width, height) / 2.0 * 0.8).toFloat()
}
- नीचे दिए गए
onSizeChanged()
कोड को जोड़कर,PointF
क्लास के लिएcomputeXYForSpeed()
एक्सटेंशन फ़ंक्शन तय करें. अनुरोध किए जाने पर,kotlin.math.cos
औरkotlin.math.sin
इंपोर्ट करें.PointF
क्लास पर मौजूद यह एक्सटेंशन फ़ंक्शन, टेक्स्ट लेबल और मौजूदा इंडिकेटर (0, 1, 2 या 3) के लिए स्क्रीन पर X और Y कोऑर्डिनेट का हिसाब लगाता है. इसके लिए, डायल की मौजूदाFanSpeed
पोज़िशन और रेडियस का इस्तेमाल किया जाता है. इसका इस्तेमालonDraw().
में किया जाएगा
private fun PointF.computeXYForSpeed(pos: FanSpeed, radius: Float) {
// Angles are in radians.
val startAngle = Math.PI * (9 / 8.0)
val angle = startAngle + pos.ordinal * (Math.PI / 4)
x = (radius * cos(angle)).toFloat() + width / 2
y = (radius * sin(angle)).toFloat() + height / 2
}
onDraw()
तरीके को ओवरराइड करें, ताकिCanvas
औरPaint
क्लास की मदद से, स्क्रीन पर व्यू रेंडर किया जा सके. अनुरोध किए जाने पर,android.graphics.Canvas
इंपोर्ट करें. यह स्केलेटन ओवरराइड है:
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
}
onDraw()
के अंदर, इस लाइन को जोड़कर पेंट का रंग स्लेटी (Color.GRAY
) या हरा (Color.GREEN
) पर सेट करें. यह इस बात पर निर्भर करता है कि पंखे की स्पीडOFF
है या कोई अन्य वैल्यू. अनुरोध किए जाने पर,android.graphics.Color
इंपोर्ट करें.
// Set dial background color to green if selection not off.
paint.color = if (fanSpeed == FanSpeed.OFF) Color.GRAY else Color.GREEN
- डायल के लिए सर्कल बनाने के लिए, इस कोड को जोड़ें. इसके लिए,
drawCircle()
तरीके का इस्तेमाल करें. इस तरीके में, सर्कल का सेंटर, सर्कल की त्रिज्या, और मौजूदा पेंट का रंग पता करने के लिए, मौजूदा व्यू की चौड़ाई और ऊंचाई का इस्तेमाल किया जाता है.width
औरheight
प्रॉपर्टी,View
सुपरक्लास की सदस्य हैं. ये व्यू के मौजूदा डाइमेंशन दिखाती हैं.
// Draw the dial.
canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, paint)
- पंखे की स्पीड दिखाने वाले इंडिकेटर मार्क के लिए, छोटा सर्कल बनाने के लिए यह कोड जोड़ें. इसके लिए,
drawCircle()
तरीके का इस्तेमाल करें इस हिस्से मेंPointF
का इस्तेमाल किया गया है.computeXYforSpeed()
एक्सटेंशन का यह तरीका, पंखे की मौजूदा रफ़्तार के आधार पर इंडिकेटर सेंटर के X,Y कोऑर्डिनेट का हिसाब लगाता है.
// Draw the indicator circle.
val markerRadius = radius + RADIUS_OFFSET_INDICATOR
pointPosition.computeXYForSpeed(fanSpeed, markerRadius)
paint.color = Color.BLACK
canvas.drawCircle(pointPosition.x, pointPosition.y, radius/12, paint)
- आखिर में, डायल के चारों ओर सही जगहों पर पंखे की स्पीड के लेबल (0, 1, 2, 3) बनाएं. इस तरीके का यह हिस्सा, हर लेबल के लिए पोज़िशन पाने के लिए
PointF.computeXYForSpeed()
को फिर से कॉल करता है. साथ ही, हर बारpointPosition
ऑब्जेक्ट का फिर से इस्तेमाल करता है, ताकि आवंटन से बचा जा सके. लेबल बनाने के लिए,drawText()
का इस्तेमाल करें.
// Draw the text labels.
val labelRadius = radius + RADIUS_OFFSET_LABEL
for (i in FanSpeed.values()) {
pointPosition.computeXYForSpeed(i, labelRadius)
val label = resources.getString(i.label)
canvas.drawText(label, pointPosition.x, pointPosition.y, paint)
}
onDraw()
तरीका पूरा होने पर ऐसा दिखता है:
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// Set dial background color to green if selection not off.
paint.color = if (fanSpeed == FanSpeed.OFF) Color.GRAY else Color.GREEN
// Draw the dial.
canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, paint)
// Draw the indicator circle.
val markerRadius = radius + RADIUS_OFFSET_INDICATOR
pointPosition.computeXYForSpeed(fanSpeed, markerRadius)
paint.color = Color.BLACK
canvas.drawCircle(pointPosition.x, pointPosition.y, radius/12, paint)
// Draw the text labels.
val labelRadius = radius + RADIUS_OFFSET_LABEL
for (i in FanSpeed.values()) {
pointPosition.computeXYForSpeed(i, labelRadius)
val label = resources.getString(i.label)
canvas.drawText(label, pointPosition.x, pointPosition.y, paint)
}
}
दूसरा चरण. लेआउट में व्यू जोड़ना
किसी ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में कस्टम व्यू जोड़ने के लिए, उसे ऐक्टिविटी के एक्सएमएल लेआउट में एक एलिमेंट के तौर पर तय करें. एक्सएमएल एलिमेंट एट्रिब्यूट का इस्तेमाल करके, इसके दिखने के तरीके और काम करने के तरीके को कंट्रोल करें. ठीक वैसे ही जैसे किसी अन्य यूज़र इंटरफ़ेस (यूआई) एलिमेंट के लिए किया जाता है.
activity_main.xml
में,dialView
के लिएImageView
टैग कोcom.example.android.customfancontroller.DialView
में बदलें औरandroid:background
एट्रिब्यूट को मिटाएं.DialView
और ओरिजनलImageView
, दोनोंView
क्लास से स्टैंडर्ड एट्रिब्यूट इनहेरिट करते हैं. इसलिए, किसी भी दूसरे एट्रिब्यूट को बदलने की ज़रूरत नहीं है. नयाDialView
एलिमेंट ऐसा दिखता है:
<com.example.android.customfancontroller.DialView
android:id="@+id/dialView"
android:layout_width="@dimen/fan_dimen"
android:layout_height="@dimen/fan_dimen"
app:layout_constraintTop_toBottomOf="@+id/customViewLabel"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:layout_marginTop="@dimen/default_margin" />
- ऐप्लिकेशन चलाएं. आपको गतिविधि में पंखे को कंट्रोल करने का विकल्प दिखेगा.
आखिरी काम यह है कि उपयोगकर्ता के व्यू पर टैप करने पर कार्रवाई करने के लिए, कस्टम व्यू को चालू करें. हर बार टैप करने पर, चुनने का इंडिकेटर अगली पोज़िशन पर जाना चाहिए: बंद-1-2-3 और फिर से बंद. साथ ही, अगर चुना गया विकल्प 1 या उससे ज़्यादा है, तो बैकग्राउंड को ग्रे से हरे रंग में बदलें. इससे पता चलता है कि पंखे की स्पीड चालू है.
कस्टम व्यू पर क्लिक करने की सुविधा चालू करने के लिए:
- व्यू की
isClickable
प्रॉपर्टी कोtrue
पर सेट करें. इससे आपकी कस्टम व्यू सुविधा, क्लिक का जवाब दे पाती है. - व्यू पर क्लिक करने पर कार्रवाइयां करने के लिए,
View
क्लास केperformClick
()
को लागू करें. invalidate()
तरीके को कॉल करें. इससे Android सिस्टम को व्यू को फिर से रेंडर करने के लिए,onDraw()
तरीके को कॉल करने का निर्देश मिलता है.
आम तौर पर, स्टैंडर्ड Android व्यू में, उपयोगकर्ता के उस व्यू पर क्लिक करने पर कोई कार्रवाई करने के लिए, OnClickListener()
को लागू किया जाता है. कस्टम व्यू के लिए, View
क्लास के performClick
()
तरीके को लागू करें. इसके बाद, super
को कॉल करें.performClick().
डिफ़ॉल्ट performClick()
तरीके से भी onClickListener()
को कॉल किया जाता है. इसलिए, performClick()
में अपनी कार्रवाइयां जोड़ी जा सकती हैं. साथ ही, onClickListener()
को आपके या अन्य डेवलपर के लिए उपलब्ध कराया जा सकता है, ताकि वे कस्टम व्यू को और ज़्यादा पसंद के मुताबिक बना सकें.
DialView.kt
में,FanSpeed
इन्यूमरेशन के अंदर, एक्सटेंशन फ़ंक्शनnext()
जोड़ें. यह फ़ंक्शन, पंखे की मौजूदा स्पीड को सूची में दी गई अगली स्पीड में बदलता है. जैसे,OFF
सेLOW
,MEDIUM
, औरHIGH
पर ले जाता है. इसके बाद, वापसOFF
पर ले जाता है. अब पूरा इन्यूमरेशन इस तरह दिखता है:
private enum class FanSpeed(val label: Int) {
OFF(R.string.fan_off),
LOW(R.string.fan_low),
MEDIUM(R.string.fan_medium),
HIGH(R.string.fan_high);
fun next() = when (this) {
OFF -> LOW
LOW -> MEDIUM
MEDIUM -> HIGH
HIGH -> OFF
}
}
DialView
क्लास में,onSizeChanged()
तरीके से ठीक पहले,init()
ब्लॉक जोड़ें. व्यू कीisClickable
प्रॉपर्टी को सही पर सेट करने से, व्यू को उपयोगकर्ता के इनपुट स्वीकार करने की अनुमति मिलती है.
init {
isClickable = true
}
- नीचे दिए गए कोड का इस्तेमाल करके,
init(),
मेंperformClick()
तरीके को बदलें.
override fun performClick(): Boolean {
if (super.performClick()) return true
fanSpeed = fanSpeed.next()
contentDescription = resources.getString(fanSpeed.label)
invalidate()
return true
}
super
को किया गया कॉल.performClick()
सबसे पहले होना चाहिए. इससे सुलभता इवेंट के साथ-साथ कॉल onClickListener()
भी चालू हो जाते हैं.
अगली दो लाइनों में, next()
तरीके का इस्तेमाल करके पंखे की स्पीड को बढ़ाया जाता है. साथ ही, व्यू के कॉन्टेंट के ब्यौरे को स्ट्रिंग रिसॉर्स पर सेट किया जाता है. यह स्ट्रिंग रिसॉर्स, पंखे की मौजूदा स्पीड (बंद, 1, 2 या 3) को दिखाता है.
आखिर में, invalidate()
तरीके से पूरे व्यू को अमान्य कर दिया जाता है. इससे onDraw()
को व्यू फिर से बनाने के लिए कॉल करना पड़ता है. अगर किसी वजह से आपके कस्टम व्यू में कोई बदलाव होता है, तो invalidate().
को कॉल करें. बदलाव की वजहों में उपयोगकर्ता का इंटरैक्शन भी शामिल है.
- ऐप्लिकेशन चलाएं. इंडिकेटर को बंद से 1 पर ले जाने के लिए,
DialView
एलिमेंट पर टैप करें. डायल का रंग हरा हो जाना चाहिए. हर बार टैप करने पर, इंडिकेटर को अगली जगह पर जाना चाहिए. जब इंडिकेटर बंद हो जाए, तो डायल का रंग फिर से स्लेटी हो जाना चाहिए.
इस उदाहरण में, कस्टम व्यू के साथ कस्टम एट्रिब्यूट इस्तेमाल करने का तरीका बताया गया है. आपने DialView
क्लास के लिए कस्टम एट्रिब्यूट तय किए हैं. इनमें हर फ़ैन डायल पोज़िशन के लिए अलग-अलग रंग दिए गए हैं.
res/values/attrs.xml
बनाएं और खोलें.<resources>
के अंदर,<declare-styleable>
रिसॉर्स एलिमेंट जोड़ें.<declare-styleable>
रिसॉर्स एलिमेंट में, तीनattr
एलिमेंट जोड़ें. हर एट्रिब्यूट के लिए एक एलिमेंट जोड़ें. साथ ही,name
औरformat
एट्रिब्यूट भी जोड़ें.format
एक तरह का टाइप होता है. इस मामले में, यहcolor
है.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DialView">
<attr name="fanColor1" format="color" />
<attr name="fanColor2" format="color" />
<attr name="fanColor3" format="color" />
</declare-styleable>
</resources>
activity_main.xml
लेआउट फ़ाइल खोलें.DialView
में,fanColor1
,fanColor2
, औरfanColor3
के लिए एट्रिब्यूट जोड़ें. साथ ही, उनकी वैल्यू को यहां दिखाए गए रंगों पर सेट करें. कस्टम एट्रिब्यूट के लिए,android:
के बजायapp:
को प्रीफ़ेस के तौर पर इस्तेमाल करें. जैसे,app:fanColor1
. ऐसा इसलिए, क्योंकि आपके कस्टम एट्रिब्यूट,android
नेमस्पेस के बजायschemas.android.com/apk/res/
your_app_package_name
नेमस्पेस से जुड़े हैं.
app:fanColor1="#FFEB3B"
app:fanColor2="#CDDC39"
app:fanColor3="#009688"
अपनी DialView
क्लास में एट्रिब्यूट इस्तेमाल करने के लिए, आपको उन्हें वापस पाना होगा. इन्हें AttributeSet
में सेव किया जाता है. अगर यह मौजूद है, तो क्लास बनाने पर इसे आपकी क्लास को सौंप दिया जाता है. init
में एट्रिब्यूट वापस पाए जाते हैं. साथ ही, एट्रिब्यूट की वैल्यू को कैश मेमोरी में सेव करने के लिए, लोकल वैरिएबल असाइन किए जाते हैं.
DialView.kt
क्लास फ़ाइल खोलें.DialView
के अंदर, एट्रिब्यूट की वैल्यू को कैश मेमोरी में सेव करने के लिए वैरिएबल तय करें.
private var fanSpeedLowColor = 0
private var fanSpeedMediumColor = 0
private var fanSeedMaxColor = 0
init
ब्लॉक में,withStyledAttributes
एक्सटेंशन फ़ंक्शन का इस्तेमाल करके यह कोड जोड़ें. आपको एट्रिब्यूट और व्यू उपलब्ध कराने होते हैं. साथ ही, आपको स्थानीय वैरिएबल सेट करने होते हैं.withStyledAttributes
को इंपोर्ट करने पर,getColor()
फ़ंक्शन भी इंपोर्ट हो जाएगा.
context.withStyledAttributes(attrs, R.styleable.DialView) {
fanSpeedLowColor = getColor(R.styleable.DialView_fanColor1, 0)
fanSpeedMediumColor = getColor(R.styleable.DialView_fanColor2, 0)
fanSeedMaxColor = getColor(R.styleable.DialView_fanColor3, 0)
}
onDraw()
में लोकल वैरिएबल का इस्तेमाल करके, पंखे की मौजूदा स्पीड के हिसाब से डायल का रंग सेट करें. पेंट का रंग सेट करने वाली लाइन (paint
.
color
=
if
(
fanSpeed
== FanSpeed.
OFF
) Color.
GRAY
else
Color.
GREEN
) को नीचे दिए गए कोड से बदलें.
paint.color = when (fanSpeed) {
FanSpeed.OFF -> Color.GRAY
FanSpeed.LOW -> fanSpeedLowColor
FanSpeed.MEDIUM -> fanSpeedMediumColor
FanSpeed.HIGH -> fanSeedMaxColor
} as Int
- अपने ऐप्लिकेशन को चलाएं, डायल पर क्लिक करें. साथ ही, हर पोज़िशन के लिए रंग की सेटिंग अलग-अलग होनी चाहिए, जैसा कि यहां दिखाया गया है.
कस्टम व्यू एट्रिब्यूट के बारे में ज़्यादा जानने के लिए, व्यू क्लास बनाना लेख पढ़ें.
सुलभता, डिज़ाइन, लागू करने, और टेस्टिंग के तरीकों का एक सेट है. इससे आपके ऐप्लिकेशन को सभी लोग इस्तेमाल कर पाते हैं. इनमें दिव्यांग लोग भी शामिल हैं.
सामान्य तौर पर, किसी व्यक्ति को Android डिवाइस इस्तेमाल करने में इन वजहों से परेशानी हो सकती है: दृष्टिहीनता, कम दिखाई देना, रंग की पहचान न कर पाना, बहरापन या सुनने की क्षमता कम होना, और चलने-फिरने में दिक्कत होना. सुलभता को ध्यान में रखकर ऐप्लिकेशन डेवलप करने से, न सिर्फ़ इन अक्षमताओं वाले उपयोगकर्ताओं को बेहतर अनुभव मिलता है, बल्कि आपके सभी उपयोगकर्ताओं को भी बेहतर अनुभव मिलता है.
Android, स्टैंडर्ड यूज़र इंटरफ़ेस (यूआई) व्यू में सुलभता से जुड़ी कई सुविधाएं डिफ़ॉल्ट रूप से उपलब्ध कराता है. जैसे, TextView
और Button
. हालांकि, कस्टम व्यू बनाते समय आपको यह ध्यान रखना होगा कि कस्टम व्यू में, सुलभता से जुड़ी सुविधाएं कैसे उपलब्ध कराई जाएंगी. जैसे, स्क्रीन पर मौजूद कॉन्टेंट के बारे में बोलकर जानकारी देना.
इस टास्क में, आपको Android के स्क्रीन रीडर, TalkBack के बारे में जानकारी मिलेगी. साथ ही, आपको अपने ऐप्लिकेशन में बदलाव करने का तरीका बताया जाएगा, ताकि DialView
कस्टम व्यू के लिए, बोलकर सुनाई जा सकने वाली जानकारी और ब्यौरे शामिल किए जा सकें.
चरण 1. TalkBack के बारे में जानें
TalkBack, Android में पहले से मौजूद स्क्रीन रीडर है. TalkBack की सुविधा चालू होने पर, उपयोगकर्ता बिना स्क्रीन देखे अपने Android डिवाइस का इस्तेमाल कर सकता है. ऐसा इसलिए, क्योंकि Android स्क्रीन पर मौजूद एलिमेंट के बारे में तेज़ आवाज़ में बताता है. दृष्टि बाधित उपयोगकर्ता, आपके ऐप्लिकेशन को इस्तेमाल करने के लिए TalkBack पर भरोसा कर सकते हैं.
इस टास्क में, आपको TalkBack को चालू करना है. इससे आपको यह समझने में मदद मिलेगी कि स्क्रीन रीडर कैसे काम करते हैं और ऐप्लिकेशन में नेविगेट कैसे किया जाता है.
- Android डिवाइस या एम्युलेटर पर, सेटिंग > सुलभता > TalkBack पर जाएं.
- TalkBack की सुविधा चालू करने के लिए, चालू/बंद करें टॉगल बटन पर टैप करें.
- अनुमतियों की पुष्टि करने के लिए, ठीक है पर टैप करें.
- अगर पूछा जाए, तो अपने डिवाइस के पासवर्ड की पुष्टि करें. अगर आपने पहली बार TalkBack चालू किया है, तो एक ट्यूटोरियल लॉन्च होगा. (ऐसा हो सकता है कि ट्यूटोरियल, पुराने डिवाइसों पर उपलब्ध न हो.)
- आंखें बंद करके ट्यूटोरियल को नेविगेट करने से आपको मदद मिल सकती है. अगर आपको आने वाले समय में ट्यूटोरियल को फिर से खोलना है, तो सेटिंग > सुलभता > TalkBack > सेटिंग > TalkBack ट्यूटोरियल लॉन्च करें पर जाएं.
CustomFanController
ऐप्लिकेशन को कंपाइल और चलाएं. इसके अलावा, इसे अपने डिवाइस पर खास जानकारी या हाल ही के बटन से भी खोला जा सकता है. TalkBack चालू होने पर, ध्यान दें कि ऐप्लिकेशन का नाम और लेबलTextView
("पंखे का कंट्रोल") का टेक्स्ट बोला जाता है. हालांकि, अगरDialView
व्यू पर टैप किया जाता है, तो व्यू की स्थिति (डायल के लिए मौजूदा सेटिंग) या व्यू को चालू करने के लिए टैप करने पर होने वाली कार्रवाई के बारे में कोई जानकारी नहीं दी जाती है.
दूसरा चरण. डायल लेबल के लिए कॉन्टेंट की जानकारी जोड़ना
कॉन्टेंट के ब्यौरे से, आपके ऐप्लिकेशन में मौजूद व्यू के मतलब और मकसद के बारे में पता चलता है. इन लेबल की मदद से, Android की TalkBack सुविधा जैसे स्क्रीन रीडर, हर एलिमेंट के फ़ंक्शन के बारे में सटीक जानकारी दे पाते हैं. ImageView
जैसे स्टैटिक व्यू के लिए, लेआउट फ़ाइल में व्यू के साथ कॉन्टेंट का ब्यौरा जोड़ा जा सकता है. इसके लिए, contentDescription
एट्रिब्यूट का इस्तेमाल करें. टेक्स्ट व्यू (TextView
और EditText
) में, व्यू में मौजूद टेक्स्ट का इस्तेमाल कॉन्टेंट के ब्यौरे के तौर पर अपने-आप होता है.
पसंद के मुताबिक बनाए गए फ़ैन कंट्रोल व्यू के लिए, आपको व्यू पर क्लिक किए जाने पर कॉन्टेंट के ब्यौरे को डाइनैमिक तरीके से अपडेट करना होगा. इससे फ़ैन की मौजूदा सेटिंग के बारे में पता चलेगा.
DialView
क्लास में सबसे नीचे,updateContentDescription()
फ़ंक्शन का एलान करें. इसमें कोई आर्ग्युमेंट या रिटर्न टाइप नहीं होता.
fun updateContentDescription() {
}
updateContentDescription()
के अंदर, कस्टम व्यू के लिएcontentDescription
प्रॉपर्टी को मौजूदा पंखे की स्पीड (बंद, 1, 2 या 3) से जुड़ी स्ट्रिंग रिसॉर्स में बदलें. ये वही लेबल हैं जिनका इस्तेमालonDraw()
में किया जाता है, जब स्क्रीन पर डायल बनाया जाता है.
fun updateContentDescription() {
contentDescription = resources.getString(fanSpeed.label)
}
- ऊपर की ओर स्क्रोल करके
init()
ब्लॉक पर जाएं. इसके बाद, उस ब्लॉक के आखिर मेंupdateContentDescription()
को कॉल करें. इससे व्यू के शुरू होने पर, कॉन्टेंट की जानकारी शुरू हो जाती है.
init {
isClickable = true
// ...
updateContentDescription()
}
performClick()
तरीके में,invalidate()
से ठीक पहलेupdateContentDescription()
को कॉल करने का एक और तरीका जोड़ें.
override fun performClick(): Boolean {
if (super.performClick()) return true
fanSpeed = fanSpeed.next()
updateContentDescription()
invalidate()
return true
}
- ऐप्लिकेशन को कंपाइल और चलाएं. साथ ही, पक्का करें कि TalkBack चालू हो. डायल व्यू की सेटिंग बदलने के लिए टैप करें. ध्यान दें कि अब TalkBack, मौजूदा लेबल (बंद, 1, 2, 3) के साथ-साथ "चालू करने के लिए दो बार टैप करें" वाक्यांश भी बोलता है.
तीसरा चरण. क्लिक ऐक्शन के लिए ज़्यादा जानकारी जोड़ना
इसके बाद, आपको कुछ और करने की ज़रूरत नहीं है. अब TalkBack की मदद से, इस व्यू का इस्तेमाल किया जा सकता है. हालांकि, अगर आपके व्यू में यह जानकारी भी शामिल हो कि इसे चालू किया जा सकता है ("चालू करने के लिए दो बार टैप करें") और इसे चालू करने पर क्या होगा ("बदलने के लिए दो बार टैप करें" या "रीसेट करने के लिए दो बार टैप करें"), तो यह ज़्यादा मददगार होगा.
इसके लिए, सुलभता डेलिगेट का इस्तेमाल करके, सुलभता नोड की जानकारी वाले ऑब्जेक्ट में व्यू की कार्रवाई (यहां, क्लिक या टैप करने की कार्रवाई) के बारे में जानकारी जोड़ी जाती है. सुलभता डेलिगेट की मदद से, कंपोज़िशन (इनहेरिटेंस के बजाय) का इस्तेमाल करके, अपने ऐप्लिकेशन की सुलभता से जुड़ी सुविधाओं को पसंद के मुताबिक बनाया जा सकता है.
इस टास्क के लिए, Android Jetpack लाइब्रेरी (androidx.*
) में मौजूद सुलभता क्लास का इस्तेमाल करें, ताकि यह पक्का किया जा सके कि ये क्लास पुराने सिस्टम के साथ काम करती हैं.
DialView.kt
में,init
ब्लॉक में, व्यू पर ऐक्सेसिबिलिटी डेलिगेट को नएAccessibilityDelegateCompat
ऑब्जेक्ट के तौर पर सेट करें. अनुरोध किए जाने पर,androidx.core.view.ViewCompat
औरandroidx.core.view.AccessibilityDelegateCompat
इंपोर्ट करें. इस रणनीति से, आपके ऐप्लिकेशन में पुराने सिस्टम के साथ काम करने की सुविधा सबसे ज़्यादा मिलती है.
ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat() {
})
AccessibilityDelegateCompat
ऑब्जेक्ट में,onInitializeAccessibilityNodeInfo()
फ़ंक्शन कोAccessibilityNodeInfoCompat
ऑब्जेक्ट से बदलें और सुपर के तरीके को कॉल करें. निर्देश मिलने पर,androidx.core.view.accessibility.AccessibilityNodeInfoCompat
इंपोर्ट करें.
ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(host: View,
info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
}
})
हर व्यू में ऐक्सेसिबिलिटी नोड का ट्री होता है. यह ज़रूरी नहीं है कि यह व्यू के लेआउट कॉम्पोनेंट से मेल खाए. Android की सुलभता सेवाएं, उन नोड पर जाती हैं, ताकि व्यू के बारे में जानकारी मिल सके. जैसे, बोले जा सकने वाले कॉन्टेंट का ब्यौरा या उस व्यू पर की जा सकने वाली संभावित कार्रवाइयां. कस्टम व्यू बनाते समय, आपको नोड की जानकारी को भी बदलना पड़ सकता है, ताकि पहुंच से जुड़ी कस्टम जानकारी दी जा सके. इस मामले में, नोड की जानकारी को बदला जाएगा, ताकि यह पता चल सके कि व्यू की कार्रवाई के लिए कस्टम जानकारी मौजूद है.
onInitializeAccessibilityNodeInfo()
के अंदर, एक नयाAccessibilityNodeInfoCompat.AccessibilityActionCompat
ऑब्जेक्ट बनाएं और उसेcustomClick
वैरिएबल को असाइन करें. कंस्ट्रक्टर मेंAccessibilityNodeInfo.ACTION_CLICK
कॉन्स्टेंट और प्लेसहोल्डर स्ट्रिंग पास करें. अनुरोध किए जाने पर, इंपोर्टAccessibilityNodeInfo
करें.
ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(host: View,
info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
val customClick = AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfo.ACTION_CLICK,
"placeholder"
)
}
})
AccessibilityActionCompat
क्लास, ऐक्सेसिबिलिटी के लिए व्यू पर की गई कार्रवाई को दिखाती है. आम तौर पर, क्लिक या टैप को कार्रवाई माना जाता है. हालांकि, फ़ोकस पाना या खोना, क्लिपबोर्ड की कार्रवाई (कट/कॉपी/चिपकाएं) या व्यू में स्क्रोल करना भी कार्रवाई में शामिल हो सकता है. इस क्लास के कंस्ट्रक्टर के लिए, कार्रवाई का कॉन्स्टेंट (यहां, AccessibilityNodeInfo.ACTION_CLICK
) और एक स्ट्रिंग की ज़रूरत होती है. TalkBack इस स्ट्रिंग का इस्तेमाल करके यह बताता है कि कार्रवाई क्या है.
- स्ट्रिंग रिसॉर्स को वापस पाने के लिए,
"placeholder"
स्ट्रिंग कोcontext.getString()
पर कॉल करने से बदलें. किसी खास संसाधन के लिए, पंखे की मौजूदा स्पीड की जांच करें. अगर स्पीड फ़िलहालFanSpeed.HIGH
है, तो स्ट्रिंग"Reset"
होगी. अगर पंखे की स्पीड कुछ और है, तो स्ट्रिंग"Change."
इन स्ट्रिंग रिसॉर्स को बाद में बनाया जाएगा.
ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(host: View,
info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
val customClick = AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfo.ACTION_CLICK,
context.getString(if (fanSpeed != FanSpeed.HIGH) R.string.change else R.string.reset)
)
}
})
customClick
की परिभाषा के लिए क्लोज़िंग पैरंटheses के बाद,addAction()
तरीके का इस्तेमाल करके, नोड की जानकारी वाले ऑब्जेक्ट में नई ऐक्सेसिबिलिटी कार्रवाई जोड़ें.
ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(host: View,
info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
val customClick = AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfo.ACTION_CLICK,
context.getString(if (fanSpeed != FanSpeed.HIGH)
R.string.change else R.string.reset)
)
info.addAction(customClick)
}
})
res/values/strings.xml
में, "बदलें" और "रीसेट करें" के लिए स्ट्रिंग रिसॉर्स जोड़ें.
<string name="change">Change</string>
<string name="reset">Reset</string>
- ऐप्लिकेशन को कंपाइल और चलाएं. साथ ही, पक्का करें कि TalkBack चालू हो. अब ध्यान दें कि "चालू करने के लिए दो बार टैप करें" वाक्यांश, अब "बदलने के लिए दो बार टैप करें" (अगर पंखे की स्पीड ज़्यादा या 3 से कम है) या "रीसेट करने के लिए दो बार टैप करें" (अगर पंखे की स्पीड पहले से ही ज़्यादा या 3 पर है) में बदल गया है. ध्यान दें कि "डबल-टैप करके..." प्रॉम्प्ट, TalkBack सेवा ही उपलब्ध कराती है.
पूरे किए गए कोडलैब का कोड डाउनलोड करें..
$ git clone https://github.com/googlecodelabs/android-kotlin-drawing-custom-views
इसके अलावा, रिपॉज़िटरी को Zip फ़ाइल के तौर पर डाउनलोड किया जा सकता है. इसके बाद, इसे अनज़िप करके Android Studio में खोला जा सकता है.
View
सबक्लास, जैसे किEditText
के लुक और व्यवहार के हिसाब से कस्टम व्यू बनाने के लिए, एक नई क्लास जोड़ें जो उस सबक्लास को बढ़ाती है. इसके बाद, सबक्लास के कुछ तरीकों को बदलकर बदलाव करें.- किसी भी साइज़ और शेप का कस्टम व्यू बनाने के लिए, एक नई क्लास जोड़ें. यह क्लास
View
को एक्सटेंड करती है. - व्यू के आकार और बुनियादी लुक को तय करने के लिए,
onDraw()
जैसेView
तरीकों को बदलें. - व्यू को फिर से ड्रा करने के लिए,
invalidate()
का इस्तेमाल करें. - परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, वैरिएबल असाइन करें. साथ ही,
onDraw()
में उनका इस्तेमाल करने से पहले, ड्रॉइंग और पेंटिंग के लिए ज़रूरी वैल्यू असाइन करें. जैसे, सदस्य वैरिएबल के शुरू होने पर. - व्यू के इंटरैक्टिव व्यवहार को दिखाने के लिए, कस्टम व्यू में
OnClickListener
() के बजायperformClick()
को बदलें. इससे आपको या अन्य Android डेवलपर को, कस्टम व्यू क्लास का इस्तेमाल करने की अनुमति मिलती है. इससे वेonClickListener()
का इस्तेमाल करके, ज़्यादा सुविधाएं दे सकते हैं. - कस्टम व्यू को एक्सएमएल लेआउट फ़ाइल में जोड़ें. साथ ही, उसके एट्रिब्यूट जोड़कर यह तय करें कि वह कैसा दिखेगा. ऐसा ही तरीका अन्य यूज़र इंटरफ़ेस (यूआई) एलिमेंट के लिए भी इस्तेमाल किया जाता है.
- कस्टम एट्रिब्यूट तय करने के लिए,
values
फ़ोल्डर मेंattrs.xml
फ़ाइल बनाएं. इसके बाद, एक्सएमएल लेआउट फ़ाइल में कस्टम व्यू के लिए कस्टम एट्रिब्यूट का इस्तेमाल किया जा सकता है.
Udacity का कोर्स:
Android डेवलपर का दस्तावेज़:
- कस्टम व्यू बनाना
@JvmOverloads
- कस्टम कॉम्पोनेंट
- Android व्यू कैसे बनाता है
onMeasure()
onSizeChanged()
onDraw()
Canvas
Paint
drawText()
setTypeface()
setColor()
drawRect()
drawOval()
drawArc()
drawBitmap()
setStyle()
invalidate()
- देखें
- इनपुट इवेंट
- Paint
- Kotlin एक्सटेंशन लाइब्रेरी android-ktx
withStyledAttributes
- Android KTX के बारे में दस्तावेज़
- Android KTX के मूल एलान के बारे में ब्लॉग
- कस्टम व्यू को ज़्यादा आसानी से ऐक्सेस करना
AccessibilityDelegateCompat
AccessibilityNodeInfoCompat
AccessibilityNodeInfoCompat.AccessibilityActionCompat
वीडियो:
इस सेक्शन में, उन छात्र-छात्राओं के लिए होमवर्क असाइनमेंट की सूची दी गई है जो किसी शिक्षक के कोर्स के हिस्से के तौर पर इस कोडलैब पर काम कर रहे हैं. शिक्षक के पास ये विकल्प होते हैं:
- अगर ज़रूरी हो, तो होमवर्क असाइन करें.
- छात्र-छात्राओं को बताएं कि होमवर्क असाइनमेंट कैसे सबमिट किए जाते हैं.
- होमवर्क असाइनमेंट को ग्रेड दें.
शिक्षक इन सुझावों का इस्तेमाल अपनी ज़रूरत के हिसाब से कर सकते हैं. साथ ही, वे चाहें, तो कोई दूसरा होमवर्क भी दे सकते हैं.
अगर आपको यह कोडलैब खुद से पूरा करना है, तो अपनी जानकारी की जांच करने के लिए, इन होमवर्क असाइनमेंट का इस्तेमाल करें.
Question 1
कस्टम व्यू को पहली बार साइज़ असाइन किए जाने पर, पोज़िशन, डाइमेंशन, और अन्य वैल्यू का हिसाब लगाने के लिए, किस तरीके को बदला जाता है?
▢ onMeasure()
▢ onSizeChanged()
▢ invalidate()
▢ onDraw()
दूसरा सवाल
अगर आपको यह दिखाना है कि एट्रिब्यूट की वैल्यू बदलने के बाद, आपको onDraw()
की मदद से व्यू को फिर से ड्रा करना है, तो यूज़र इंटरफ़ेस (यूआई) थ्रेड से कौनसे तरीके को कॉल किया जाता है?
▢ onMeasure()
▢ onSizeChanged()
▢ invalidate()
▢ getVisibility()
तीसरा सवाल
अपने कस्टम व्यू में इंटरैक्टिविटी जोड़ने के लिए, आपको View
के किस तरीके को बदलना चाहिए?
▢ setOnClickListener()
▢ onSizeChanged()
▢ isClickable()
▢ performClick()
इस कोर्स में मौजूद अन्य कोडलैब के लिंक के लिए, Advanced Android in Kotlin कोडलैब का लैंडिंग पेज देखें.