यह कोडलैब, Kotlin में बेहतर Android का हिस्सा है. अगर आप कोडलैब के क्रम में काम करते हैं, लेकिन यह ज़रूरी नहीं है, तो आपको इस कोर्स का पूरा फ़ायदा मिलेगा. सभी कोर्स कोडलैब Kotlin कोडलैब के लैंडिंग पेज पर बेहतर Android पेज पर दिए गए हैं.
परिचय
Android में, आपके पास व्यू में कस्टम 2D ग्राफ़िक और ऐनिमेशन लागू करने के लिए कई तकनीकें उपलब्ध हैं.
ड्रॉ करने लायक के इस्तेमाल के अलावा, आप Canvas
क्लास के ड्रॉइंग के तरीकों का इस्तेमाल करके 2D ड्रॉइंग भी बना सकते हैं. Canvas
2D ड्रॉइंग प्लैटफ़ॉर्म है, जो ड्रॉइंग के तरीके बताता है. यह तब काम आता है, जब आपके ऐप्लिकेशन को लगातार अपने-आप फिर से काम करने की ज़रूरत होती है, क्योंकि उपयोगकर्ता को समय के साथ बदलाव दिखते हैं. इस कोडलैब में, आप View
में दिखाए गए कैनवस को बनाने और बनाने का तरीका जान सकते हैं.
आप कैनवस पर, ये कार्रवाइयां कर सकते हैं:
- पूरे कैनवस को रंग से भरें.
- आयत, आकार, और पाथ जैसे आकार बनाने में मदद करें, जैसा कि
Paint
ऑब्जेक्ट में बताया गया है.Paint
ऑब्जेक्ट में ज्यामिति को बनाने के तरीके (जैसे कि लाइन, आयत, अंडाकार, और पाथ) की शैली और रंग की जानकारी होती है. जैसे, टेक्स्ट का टाइपफ़ेस. - अनुवाद, स्केलिंग या कस्टम ट्रांसफ़ॉर्मेशन जैसे ट्रांसफ़ॉर्मेशन लागू करें.
- क्लिप यानी कि कैनवस के आकार या पाथ को चुनकर, उसके दिखने वाले हिस्सों की जानकारी दें.
आप Android ड्रॉइंग के बारे में कैसे सोच सकते हैं (सुपर-आसान!)
Android या किसी दूसरे आधुनिक सिस्टम पर ड्रॉइंग करना, एक मुश्किल प्रोसेस है. इसमें, ऐब्स्ट्रैक्शन की लेयर, और हार्डवेयर के ऑप्टिमाइज़ेशन शामिल हैं. Android का ड्रॉ किस तरह एक दिलचस्प विषय है जिसके बारे में लिखा गया है. साथ ही, इसमें दी गई जानकारी भी इस कोडलैब के दायरे से बाहर है.
इस कोडलैब और उसके ऐप्लिकेशन के संदर्भ में, जो फ़ुल-स्क्रीन व्यू में कैनवस पर दिखता है, आप इस तरीके से इसे समझ सकते हैं.
- आप जो ड्रॉ कर रहे हैं उसे दिखाने के लिए आपको एक व्यू चाहिए. यह Android सिस्टम के उपलब्ध कराए गए व्यू में से एक हो सकता है. इसके अलावा, आप इस कोडलैब में, एक ऐसा कस्टम व्यू बनाते हैं जो आपके ऐप्लिकेशन (
MyCanvasView
) के कॉन्टेंट व्यू के तौर पर काम करता है. - सभी व्यू की तरह, यह व्यू अपने कैनवस (
canvas
) के साथ आता है. - किसी व्यू के कैनवस पर ड्रॉ करने के सबसे बुनियादी तरीके के लिए, आप उसके
onDraw()
तरीके को ओवरराइड करके उसके कैनवस पर ड्रॉ करते हैं. - ड्रॉइंग बनाते समय, आपको पहले बनाई गई चीज़ों को कैश मेमोरी में सेव करना होगा. आपके डेटा को कैश करने के कई तरीके हैं, एक बिट मैप में है (
extraBitmap
). दूसरा तरीका है कि अपने संग्रह का इतिहास, निर्देशांक और निर्देशों के तौर पर सेव करना. - कैनवस ड्रॉइंग API का इस्तेमाल करके, अपने कैशिंग बिट मैप (
extraBitmap
) पर ड्रॉइंग बनाने के लिए, आप कैश मेमोरी में सेव किए गए बिट मैप के लिए कैश मेमोरी में सेव करने वाला कैनवस (extraCanvas
) बनाते हैं. - इसके बाद, आप कैश मेमोरी में सेव किए गए कैनवस (
extraCanvas
) पर ड्रॉ करते हैं, जो आपके कैश मेमोरी बिट मैप (extraBitmap
) पर दिखता है. - स्क्रीन पर ड्रॉ की गई हर चीज़ को दिखाने के लिए, आप व्यू और #39;s कैनवस (
canvas
) को कैशिंग बिट मैप (extraBitmap
) बनाने के लिए कहते हैं.
आपको क्या पता होना चाहिए
- गतिविधि और बेसिक लेआउट की मदद से ऐप्लिकेशन बनाने और Android Studio का इस्तेमाल करके उसे चलाने का तरीका.
- इवेंट हैंडलर को व्यू से जोड़ने का तरीका.
- पसंद के मुताबिक व्यू बनाने का तरीका.
आप इन चीज़ों के बारे में जानेंगे
Canvas
बनाने और उपयोगकर्ता के टच के जवाब में उसे बनाने का तरीका.
आप क्या कर पाएंगे!
- ऐसा ऐप्लिकेशन बनाएं जो स्क्रीन को छूने वाले उपयोगकर्ता के जवाब में, स्क्रीन पर लाइन बनाता हो.
- मोशन इवेंट को कैप्चर करें. साथ ही, स्क्रीन पर फ़ुल-स्क्रीन कस्टम व्यू में दिखने वाले कैनवस पर लाइन बनाएं.
MiniPaint ऐप्लिकेशन, उपयोगकर्ता के छूने के जवाब में एक लाइन दिखाने के लिए, कस्टम व्यू का इस्तेमाल करता है, जैसा कि नीचे स्क्रीनशॉट में दिखाया गया है.
पहला चरण. MiniPaint प्रोजेक्ट बनाएं
- मिनीपेंट नाम का एक नया Kotlin प्रोजेक्ट बनाएं, जो खाली गतिविधि टेंप्लेट का इस्तेमाल करता है.
app/res/values/colors.xml
फ़ाइल खोलें और यहां दिए गए दो रंगों को जोड़ें.
<color name="colorBackground">#FFFF5500</color>
<color name="colorPaint">#FFFFEB3B</color>
styles.xml
खोलें- दी गई
AppTheme
शैली के पैरंट में,DarkActionBar
कोNoActionBar
से बदलें. इससे ऐक्शन बार हट जाता है, ताकि आप फ़ुलस्क्रीन कर सकें.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
दूसरा चरण. MyCanvasView क्लास बनाएं
इस कदम में, आप ड्रॉइंग के लिए, एक कस्टम व्यू MyCanvasView
बनाते हैं.
app/java/com.example.android.minipaint
पैकेज में,MyCanvasView
नाम से एक नया > Kotlin फ़ाइल/क्लास बनाएं.MyCanvasView
क्लास कोView
क्लास बढ़ाएं औरcontext: Context
में पास करें. सुझाए गए इंपोर्ट स्वीकार करें.
import android.content.Context
import android.view.View
class MyCanvasView(context: Context) : View(context) {
}
तीसरा चरण. MyCanvasView को कॉन्टेंट व्यू के तौर पर सेट करें
आप MyCanvasView
में क्या बनाएंगे, यह दिखाने के लिए आपको इसे MainActivity
के कॉन्टेंट व्यू के तौर पर सेट करना होगा.
strings.xml
खोलें और एक स्ट्रिंग तय करें, ताकि व्यू और #39; के कॉन्टेंट की जानकारी के लिए इस्तेमाल किया जा सके.
<string name="canvasContentDescription">Mini Paint is a simple line drawing app.
Drag your fingers to draw. Rotate the phone to clear.</string>
MainActivity.kt
खोलेंonCreate()
में जाकर,setContentView(R.layout.activity_main)
को मिटाएं.MyCanvasView
का इंस्टेंस बनाएं.
val myCanvasView = MyCanvasView(this)
- इसके नीचे,
myCanvasView
के लेआउट के लिए फ़ुल स्क्रीन का अनुरोध करें.myCanvasView
परSYSTEM_UI_FLAG_FULLSCREEN
फ़्लैग सेट करके ऐसा करें. इस तरह, व्यू पूरी तरह से स्क्रीन को भर देता है.
myCanvasView.systemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN
- कॉन्टेंट की जानकारी जोड़ें.
myCanvasView.contentDescription = getString(R.string.canvasContentDescription)
- इसके नीचे, कॉन्टेंट व्यू को
myCanvasView
पर सेट करें.
setContentView(myCanvasView)
- अपना ऐप्लिकेशन चलाएं. आपको पूरी तरह से सफ़ेद स्क्रीन दिखेगी, क्योंकि कैनवस का कोई साइज़ नहीं है और आपने अब तक कुछ भी नहीं बनाया है.
पहला चरण. onSizeChanged() बदलें
जब भी किसी व्यू का साइज़ बदलता है, तब Android सिस्टम onSizeChanged()
तरीके का इस्तेमाल करता है. व्यू की शुरुआत बिना साइज़ के होती है, इसलिए ऐक्टिविटी के पहली बार बनाए जाने और उसे बढ़ाने के बाद, व्यू के onSizeChanged()
तरीके को भी कॉल किया जाता है. इसलिए, व्यू और #39 साइज़ के कैनवस बनाने और सेट अप करने के लिए, यह onSizeChanged()
तरीका सबसे सही जगह है.
MyCanvasView
में, क्लास लेवल पर, कैनवस और बिट मैप के लिए वैरिएबल तय करें.extraCanvas
औरextraBitmap
को कॉल करें. ये पहले बनाई गई चीज़ों को कैश मेमोरी में सेव करने के लिए आपके बिट मैप और कैनवस हैं.
private lateinit var extraCanvas: Canvas
private lateinit var extraBitmap: Bitmap
- कैनवस के बैकग्राउंड के रंग के लिए, क्लास लेवल का वैरिएबल
backgroundColor
तय करें और उसे पहले तय किए गएcolorBackground
से शुरू करें.
private val backgroundColor = ResourcesCompat.getColor(resources, R.color.colorBackground, null)
MyCanvasView
में,onSizeChanged()
वाले तरीके को बदलें. इस कॉलबैक तरीके को Android सिस्टम कहते हैं जिसमें बदले गए स्क्रीन डाइमेंशन होते हैं. इसका मतलब है कि नई चौड़ाई और ऊंचाई (जिसमें बदलाव करना है) और पुरानी चौड़ाई और ऊंचाई (जिससे बदलाव करना है).
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
super.onSizeChanged(width, height, oldWidth, oldHeight)
}
onSizeChanged()
के अंदर, नई चौड़ाई और ऊंचाई वालेBitmap
का एक इंस्टेंस बनाएं. ये स्क्रीन के आकार होते हैं और इन्हेंextraBitmap
को असाइन करें. तीसरा तर्क बिट मैप कलर कॉन्फ़िगरेशन है.ARGB_8888
हर रंग को 4 बाइट में स्टोर करता है और इसका सुझाव दिया जाता है.
extraBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
extraBitmap
सेCanvas
इंस्टेंस बनाएं और इसेextraCanvas
को असाइन करें.
extraCanvas = Canvas(extraBitmap)
- बैकग्राउंड का रंग बताएं, जिसमें
extraCanvas
को भरना है.
extraCanvas.drawColor(backgroundColor)
onSizeChanged()
को देखकर, हर बार फ़ंक्शन के काम करने पर एक नया बिट मैप और कैनवस बनाया जाता है. आपको एक नया बिट मैप चाहिए, क्योंकि साइज़ बदल गया है. हालांकि, यह मेमोरी का लीक होना है, जो पुराने बिट मैप के आस-पास ही रह गया है. इसे ठीक करने के लिए,super
में कॉल के ठीक बाद यह कोड जोड़कर अगला कोड बनाने से पहलेextraBitmap
को रीसाइकल करें.
if (::extraBitmap.isInitialized) extraBitmap.recycle()
दूसरा चरण. onDraw() बदलें
MyCanvasView
के लिए सभी ड्रॉइंग onDraw()
में होती हैं.
शुरू करने के लिए, कैनवस दिखाएं. साथ ही, स्क्रीन को बैकग्राउंड के रंग से भरें जिसे आपने onSizeChanged()
में सेट किया है.
onDraw()
को ओवरराइड करें और व्यू से जुड़े कैनवस परextraBitmap
कैश की गई सामग्री को ड्रॉ करें.drawBitmap()
Canvas
तरीका कई वर्शन में उपलब्ध है. इस कोड में, आप ऊपर बाएं कोने में बिट मैप, x और y निर्देशांक (और पिक्सल में) देते हैं, औरPaint
के लिएnull
, क्योंकि आप इसे बाद में सेट करेंगे.
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawBitmap(extraBitmap, 0f, 0f, null)
}
ध्यान दें कि onDraw()
को भेजा गया कैनवस और सिस्टम, बिट मैप को दिखाने के लिए जिस कैनवस का इस्तेमाल करते हैं वह onSizeChanged()
तरीके में बनाए गए कैनवस से अलग होता है. आप बिटमैप पर ड्रॉ करने के लिए भी इसका इस्तेमाल करते हैं.
- अपना ऐप्लिकेशन चलाएं. आपको बैकग्राउंड के खास रंग से पूरी स्क्रीन दिखाई देनी चाहिए.
ड्रॉ करने के लिए, आपको एक Paint
ऑब्जेक्ट की ज़रूरत होती है, जो बताता है कि ड्रॉ किए जाने पर स्टाइल कैसे बनाई जाती है और Path
, जो ड्रॉ की जा रही है.
पहला चरण. पेंट ऑब्जेक्ट शुरू करना
- MyCanvasView.kt में, सबसे ऊपर फ़ाइल लेवल पर, स्ट्रोक की चौड़ाई के लिए एक कॉन्सटेंट तय करें.
private const val STROKE_WIDTH = 12f // has to be float
MyCanvasView
के क्लास लेवल पर, जिस वैरिएबल के साथ ड्रॉ करना है उसे कलर होल्ड करने के लिए, एक वैरिएबलdrawColor
तय करें और इसे उसcolorPaint
रिसॉर्स से शुरू करें जिसे आपने पहले तय किया था.
private val drawColor = ResourcesCompat.getColor(resources, R.color.colorPaint, null)
- नीचे दिए गए क्लास लेवल पर,
Paint
ऑब्जेक्ट के लिए एक वैरिएबलpaint
जोड़ें और उसे इस तरह शुरू करें.
// Set up the paint with which to draw.
private val paint = Paint().apply {
color = drawColor
// Smooths out edges of what is drawn without affecting shape.
isAntiAlias = true
// Dithering affects how colors with higher-precision than the device are down-sampled.
isDither = true
style = Paint.Style.STROKE // default: FILL
strokeJoin = Paint.Join.ROUND // default: MITER
strokeCap = Paint.Cap.ROUND // default: BUTT
strokeWidth = STROKE_WIDTH // default: Hairline-width (really thin)
}
paint
काcolor
, वहdrawColor
है जिसे आपने पहले तय किया था.isAntiAlias
से पता चलता है कि एज स्मूदिंग लागू करनी है या नहीं.isAntiAlias
कोtrue
पर सेट करने से, आकार पर असर डाले बिना ड्रॉइंग के किनारों को साफ़ किया जाता है.isDither
, जबtrue
, डिवाइस के मुकाबले ज़्यादा सटीक रंगों वाले नमूनों को प्रभावित करता है, तो इसका नमूना लिया जाता है. उदाहरण के लिए, इमेज की कलर रेंज को 256 (या उससे कम) रंग कम करने का सबसे आम तरीका है.style
, स्ट्रोक में सेट की जाने वाली पेंटिंग के टाइप को सेट करता है. यह एक लाइन है.Paint.Style
से पता चलता है कि बनाया गया प्रिमिटिव, भरे गए, स्ट्रोक या दोनों (एक ही रंग में) है या नहीं. जिस ऑब्जेक्ट पर पेंट लागू किया जाता है उसे डिफ़ॉल्ट रूप से भरना होता है. (&kot&Fit&कोटेशन; आकार के अंदर का रंग, जबकि &kot;स्ट्रोक&कोटेशन; अपनी आउटलाइन के मुताबिक होता है.)Paint.Join
में सेstrokeJoin
बताती है कि किसी स्ट्रोक पाथ पर लाइन और कर्व सेगमेंट कैसे जुड़ते हैं. डिफ़ॉल्ट रूप से,MITER
होती है.strokeCap
, लाइन के अंत के आकार को कैप के तौर पर सेट करता है.Paint.Cap
बताता है कि स्ट्रोक और लाइन के शुरू और खत्म होने का तरीका कैसे होता है. डिफ़ॉल्ट रूप से,BUTT
होती है.strokeWidth
, स्ट्रोक की चौड़ाई को पिक्सल में बताता है. डिफ़ॉल्ट रूप से, हेयरलाइन की चौड़ाई बहुत कम होती है. इसलिए, यह पहले से तयSTROKE_WIDTH
कॉन्सटेंट पर सेट होता है.
दूसरा चरण. पाथ ऑब्जेक्ट को शुरू करें
Path
उपयोगकर्ता के ड्रॉइंग का पाथ है.
MyCanvasView
में, एक वैरिएबलpath
जोड़ें. इसेPath
ऑब्जेक्ट की मदद से शुरू करें. इससे, उपयोगकर्ता के पेज को फ़ॉलो करते समय ड्रॉ किए जाने वाले पाथ को सेव किया जा सकता है.Path
के लिएandroid.graphics.Path
इंपोर्ट करें.
private var path = Path()
पहला चरण. डिसप्ले पर होने वाली हलचल पर जवाब दें
जब भी उपयोगकर्ता डिसप्ले को छूता है, तब व्यू पर onTouchEvent()
तरीके को कॉल किया जाता है.
MyCanvasView
में,event
में पास किए गएx
औरy
निर्देशांकों को कैश करने के लिए,onTouchEvent()
तरीके को बदलें. इसके बाद, स्क्रीन पर नीचे की ओर छूने, स्क्रीन पर ले जाने, और स्क्रीन को छूने के लिए मोशन इवेंट को हैंडल करने के लिए, एकwhen
एक्सप्रेशन का इस्तेमाल करें. ये इवेंट, स्क्रीन पर लाइन बनाने के लिए दिलचस्पी दिखाने वाले इवेंट हैं. हर इवेंट टाइप के लिए, Utility से जुड़े किसी तरीके पर कॉल करें, जैसा कि नीचे कोड में दिखाया गया है. टच इवेंट की पूरी सूची के लिए,MotionEvent
क्लास के दस्तावेज़ देखें.
override fun onTouchEvent(event: MotionEvent): Boolean {
motionTouchEventX = event.x
motionTouchEventY = event.y
when (event.action) {
MotionEvent.ACTION_DOWN -> touchStart()
MotionEvent.ACTION_MOVE -> touchMove()
MotionEvent.ACTION_UP -> touchUp()
}
return true
}
- क्लास लेवल पर, मौजूदा टच इवेंट (
MotionEvent
कोऑर्डिनेट) के x और y काेऑर्डिनेट में कैश मेमोरी में सेव करने के लिए,motionTouchEventX
औरmotionTouchEventY
वैरिएबल जोड़ें. उन्हें0f
के साथ शुरू करें.
private var motionTouchEventX = 0f
private var motionTouchEventY = 0f
- तीन फ़ंक्शन
touchStart()
,touchMove()
, औरtouchUp()
के लिए स्टब बनाएं.
private fun touchStart() {}
private fun touchMove() {}
private fun touchUp() {}
- आपका कोड बन जाना चाहिए और चलना चाहिए, लेकिन आपको रंगीन बैकग्राउंड से कुछ अलग नहीं दिखेगा.
दूसरा चरण. TouchStart() लागू करें
यह तरीका तब कॉल किया जाता है, जब उपयोगकर्ता पहली बार स्क्रीन को छूता है.
- क्लास लेवल पर, नई x और y वैल्यू को कैश मेमोरी में सेव करने के लिए वैरिएबल जोड़ें. जब उपयोगकर्ता हिलना-डुलना बंद कर देता है और अपना टच हटा लेता है, तो अगले पाथ की शुरुआत यहां से होती है (लाइन का अगला सेगमेंट).
private var currentX = 0f
private var currentY = 0f
touchStart()
तरीके को इस तरह लागू करें.path
को रीसेट करें, टच इवेंट (motionTouchEventX
औरmotionTouchEventY
) के x-y निर्देशांक पर जाएं, और उस मान के लिएcurrentX
औरcurrentY
असाइन करें.
private fun touchStart() {
path.reset()
path.moveTo(motionTouchEventX, motionTouchEventY)
currentX = motionTouchEventX
currentY = motionTouchEventY
}
तीसरा चरण. Touchmove() लागू करना
- कक्षा के लेवल पर,
touchTolerance
वैरिएबल जोड़ें और उसेViewConfiguration.get(context).scaledTouchSlop
पर सेट करें.
private val touchTolerance = ViewConfiguration.get(context).scaledTouchSlop
पाथ का इस्तेमाल करके, हर पिक्सल को ड्रॉ नहीं करना होता और हर बार डिसप्ले को रीफ़्रेश करने के लिए अनुरोध करना पड़ता है. इसके बजाय, आप ज़्यादा बेहतर परफ़ॉर्मेंस के लिए पॉइंट के बीच के पाथ को इंटरपोलेट कर सकते हैं और ऐसा करेंगे.
- अगर उंगली मुश्किल से ही हिल रही है, तो इसका इस्तेमाल करने की कोई ज़रूरत नहीं है.
- अगर उंगली को
touchTolerance
से कम दूरी पर ले जाया गया है, तो ड्रॉइंग न करें. - इससे पहले कि
scaledTouchSlop
सिस्टम को यह लगे कि उपयोगकर्ता स्क्रोल कर रहा है, टच की गई दूरी को पिक्सल में बदल सकता है.
touchMove()
तरीका तय करें. यात्रा में तय की गई दूरी का हिसाब लगाएं,dx
,dy
), दोनों पॉइंट के बीच में एक कर्व बनाएं और उसेpath
में सेव करें. इसके बाद, रनिंगcurrentX
औरcurrentY
टैल को अपडेट करें औरpath
ड्रॉ करें. फिर अपडेट किए गएpath
के साथ, स्क्रीन को ज़बरदस्ती फिर से खींचने के लिएinvalidate()
को कॉल करें.
private fun touchMove() {
val dx = Math.abs(motionTouchEventX - currentX)
val dy = Math.abs(motionTouchEventY - currentY)
if (dx >= touchTolerance || dy >= touchTolerance) {
// QuadTo() adds a quadratic bezier from the last point,
// approaching control point (x1,y1), and ending at (x2,y2).
path.quadTo(currentX, currentY, (motionTouchEventX + currentX) / 2, (motionTouchEventY + currentY) / 2)
currentX = motionTouchEventX
currentY = motionTouchEventY
// Draw the path in the extra bitmap to cache it.
extraCanvas.drawPath(path, paint)
}
invalidate()
}
इस तरीके के बारे में ज़्यादा जानकारी:
- तय की गई दूरी का हिसाब लगाएं (
dx, dy
). - अगर हलचल, टच टॉलरेंस से ज़्यादा थी, तो पाथ में एक सेगमेंट जोड़ें.
- अगले सेगमेंट के लिए, इस सेगमेंट के एंडपॉइंट पर शुरुआती पॉइंट सेट करें.
lineTo()
के बजायquadTo()
का इस्तेमाल करने पर, कोनों के बिना आसानी से ड्रॉ की जा सकने वाली लाइन बनाएं. बेज़ियर कर्व्स देखें.invalidate()
को कॉल करें (कुलonDraw()
को कॉल करें और) व्यू को फिर से ड्रॉ करें.
चौथा चरण: TouchUp() लागू करना
जब उपयोगकर्ता अपना टच वापस लेता है, तो सिर्फ़ पाथ को रीसेट करना होता है, ताकि वह फिर से ड्रॉ न हो. कुछ भी तैयार नहीं किया गया है, इसलिए किसी अमान्य जानकारी की ज़रूरत नहीं है.
touchUp()
तरीका लागू करें.
private fun touchUp() {
// Reset the path so it doesn't get drawn again.
path.reset()
}
- अपना कोड चलाएं और स्क्रीन पर ड्रॉ करने के लिए, अपनी उंगली का इस्तेमाल करें. ध्यान दें कि अगर डिवाइस को घुमाते हैं, तो स्क्रीन से पूरा डेटा मिट जाता है, क्योंकि ड्रॉइंग की स्थिति सेव नहीं होती है. इस सैंपल ऐप्लिकेशन के लिए, इस डिज़ाइन को इस तरह बनाया गया है कि उपयोगकर्ता आसानी से स्क्रीन को मिटा सके.
पांचवां चरण: स्केच के चारों ओर फ़्रेम बनाना
जैसे ही उपयोगकर्ता स्क्रीन पर ड्रॉ करता है, आपका ऐप्लिकेशन पाथ बनाता है और उसे बिट मैप extraBitmap
में सेव करता है. onDraw()
तरीके से, व्यू और #39; कैनवस में ज़्यादा बिट मैप दिखता है. आप onDraw()
में और ड्रॉइंग कर सकते हैं. उदाहरण के लिए, आप बिट मैप बनाने के बाद आकार बना सकते हैं.
इस चरण में, तस्वीर के किनारे पर एक फ़्रेम बनाया जाता है.
MyCanvasView
में,frame
नाम का एक वैरिएबल जोड़ें, जिसमेंRect
ऑब्जेक्ट होता है.
private lateinit var frame: Rect
onSizeChanged()
के आखिर में, इनसेट सेट करें. साथ ही, नए डाइमेंशन और इनसेट का इस्तेमाल करके, फ़्रेम बनाने के लिए इस्तेमाल किया जाने वालाRect
बनाने के लिए कोड जोड़ें.
// Calculate a rectangular frame around the picture.
val inset = 40
frame = Rect(inset, inset, width - inset, height - inset)
onDraw()
में, बिट मैप बनाने के बाद, एक आयत बनाएं.
// Draw a frame around the canvas.
canvas.drawRect(frame, paint)
- अपना ऐप्लिकेशन चलाएं. फ़्रेम पर ध्यान दें.
टास्क (ज़रूरी नहीं): पाथ में डेटा सेव करना
मौजूदा ऐप्लिकेशन में, ड्रॉइंग की जानकारी बिट मैप में सेव की जाती है. हालांकि, यह एक अच्छा समाधान है, लेकिन ड्रॉइंग की जानकारी सेव करने के लिए, सिर्फ़ यही एक तरीका नहीं है. आप अपना ड्रॉइंग इतिहास कैसे सेव करते हैं, यह ऐप्लिकेशन और आपकी अलग-अलग ज़रूरतों पर निर्भर करता है. उदाहरण के लिए, अगर आप आकार बना रहे हैं, तो आप जगह और डाइमेंशन के साथ आकारों की सूची सेव कर सकते हैं. MiniPaint ऐप्लिकेशन के लिए, पाथ को Path
के तौर पर सेव किया जा सकता है. अगर आप इसे आज़माना चाहते हैं, तो नीचे इसका तरीका बताया गया है.
MyCanvasView
में मौजूद,extraCanvas
औरextraBitmap
के सभी कोड हटाएं.- अब तक पाथ के लिए वैरिएबल जोड़ें और मौजूदा पाथ के लिए पाथ जोड़ें.
// Path representing the drawing so far
private val drawing = Path()
// Path representing what's currently being drawn
private val curPath = Path()
onDraw()
में बिट मैप बनाने के बजाय, स्टोर किए गए और मौजूदा पाथ बनाएं.
// Draw the drawing so far
canvas.drawPath(drawing, paint)
// Draw any current squiggle
canvas.drawPath(curPath, paint)
// Draw a frame around the canvas
canvas.drawRect(frame, paint)
touchUp()
में मौजूदा पाथ को मौजूदा पाथ में जोड़ें और मौजूदा पाथ को रीसेट करें.
// Add the current path to the drawing so far
drawing.addPath(curPath)
// Rewind the current path for the next touch
curPath.reset()
- अपना ऐप्लिकेशन चलाएं. इसके बाद, आपको कुछ खास फ़र्क़ नहीं डालना होगा.
अब खत्म हो चुके कोडलैब के लिए कोड डाउनलोड करें.
$ git clone https://github.com/googlecodelabs/android-kotlin-drawing-canvas
इसके अलावा, आप रिपॉज़िटरी को एक ZIP फ़ाइल के रूप में डाउनलोड कर सकते हैं, इसे अनज़िप कर सकते हैं, और Android Studio में खोल सकते हैं.
Canvas
2D ड्रॉइंग प्लैटफ़ॉर्म है, जो ड्रॉइंग के तरीके बताता है.- इसे दिखाने वाले
Canvas
कोView
इंस्टेंस से जोड़ा जा सकता है. Paint
ऑब्जेक्ट में ज्यामिति को बनाने के तरीके (जैसे कि लाइन, आयत, अंडाकार, और पाथ) और टेक्स्ट की शैली और रंग की जानकारी होती है.- कैनवस के साथ काम करने का एक आम पैटर्न यह है कि आप कस्टम व्यू बनाएं और
onDraw()
औरonSizeChanged()
तरीकों को बदल दें. - उपयोगकर्ता के हाथ के जेस्चर (हाव-भाव) कैप्चर करने के लिए,
onTouchEvent()
का तरीका बदलें. इसके बाद, चीज़ों का ड्रॉइंग बनाकर उनका जवाब दें. - समय के साथ बदलने वाली ड्रॉइंग की जानकारी कैश मेमोरी में रखने के लिए, आप एक और बिट मैप का इस्तेमाल कर सकते हैं. इसके अलावा, आप आकार या पाथ सेव कर सकते हैं.
Udcity कोर्स:
Android डेवलपर दस्तावेज़:
Canvas
क्लासBitmap
क्लासView
क्लासPaint
क्लासBitmap.config
कॉन्फ़िगरेशनPath
क्लास- बेज़ियर कर्व विकिपीडिया पेज
- कैनवस और ड्रॉ करने लायक चीज़ें
- ग्राफ़िक्स आर्किटेक्चर लेखों की सीरीज़ (बेहतर)
- ड्रॉ करने लायक
- onDraw()
- onSizeChanged()
MotionEvent
ViewConfiguration.get(context).scaledTouchSlop
इस सेक्शन में उन छात्र-छात्राओं के लिए गृहकार्य की असाइनमेंट की सूची दी गई है जो इस कोडलैब के ज़रिए एक शिक्षक की देखरेख में कोर्स में काम कर रहे हैं. यह क्रिएटर का काम #33 पर निर्भर करता है:
- अगर ज़रूरी हो, तो होमवर्क असाइन करें.
- छात्र-छात्राओं को होमवर्क के असाइनमेंट सबमिट करने के तरीके के बारे में बताएं.
- होमवर्क असाइनमेंट को ग्रेड दें.
शिक्षक इन सुझावों का इस्तेमाल जितनी चाहें उतनी कम या ज़्यादा कर सकते हैं. साथ ही, उन्हें अपने हिसाब से कोई भी होमवर्क असाइन करना चाहिए.
अगर आप इस कोडलैब के ज़रिए खुद काम कर रहे हैं, तो बेझिझक इन होमवर्क असाइनमेंट का इस्तेमाल करें.
इन सवालों के जवाब दें
पहला सवाल
Canvas
के साथ काम करने के लिए, इनमें से कौनसा कॉम्पोनेंट ज़रूरी है? लागू होने वाले सभी विकल्प चुनें.
▢ Bitmap
▢ Paint
▢ Path
▢ View
दूसरा सवाल
invalidate()
के लिए कॉल क्या करता है (सामान्य शब्दों में)?
▢ अमान्य है और आपके ऐप्लिकेशन को रीस्टार्ट करता है.
▢ बिटमैप से ड्रॉइंग मिटाता है.
▢ बताता है कि पिछला कोड नहीं चलाना चाहिए.
▢ सिस्टम को बताता है कि उसे स्क्रीन को फिर से लाल करना होगा.
तीसरा सवाल
Canvas
, Bitmap
, और Paint
ऑब्जेक्ट का फ़ंक्शन क्या है?
▢ 2D ड्रॉइंग प्लैटफ़ॉर्म, स्क्रीन पर बिट मैप दिखाया जाता है, ड्रॉइंग के लिए स्टाइलिंग की जानकारी.
▢ 3D ड्रॉइंग प्लैटफ़ॉर्म, पाथ को कैश करने के लिए बिट मैप, ड्रॉइंग के लिए स्टाइल की जानकारी.
▢ 2D ड्रॉइंग प्लैटफ़ॉर्म, स्क्रीन पर बिट मैप दिखाया जाता है, जो व्यू के लिए स्टाइल होता है.
▢ ड्रॉइंग के लिए कैश मेमोरी, ड्रॉइंग के लिए बिटमैप, ड्रॉइंग के लिए स्टाइल की जानकारी.
इस कोर्स में दिए गए दूसरे कोडलैब के लिंक के लिए, Kotlin कोडलैब के लैंडिंग पेज में ऐडवांस्ड Android देखें.