एंड्रॉइड में Canvas और Paint से लाइन (और शेप्स) ड्रा करना
एंड्रॉइड में कस्टम ड्राइंग के लिए Canvas (ड्राइंग सतह) और Paint (स्टाइल: रंग, चौड़ाई, स्ट्रोक/फिल) उपयोग करते हैं। दो मुख्य दृष्टिकोण हैं:
- कस्टम View (
onDraw()ओवरराइड) — **सिफारिश किया गया**, पुन: उपयोग योग्य, प्रदर्शन अच्छा। - Bitmap पर ड्रा करके ImageView में सेट करना — मूल लेख का तरीका, लेकिन कम लचीला।
चरण 1: नया प्रोजेक्ट बनाएं
Android Studio → File → New → New Project → "Empty Activity" → Finish।
चरण 2: विधि 1 — कस्टम View (सर्वोत्तम अभ्यास)
DrawView.java
package com.example.drawlinedemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class DrawView extends View {
private final Paint paint = new Paint();
private float lineStartX = 50, lineStartY = 50;
private float lineEndX = 300, lineEndY = 300;
public DrawView(Context context) {
super(context);
init();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
paint.setColor(Color.RED);
paint.setStrokeWidth(8f);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true); // स्मूथ एज
paint.setStrokeCap(Paint.Cap.ROUND); // गोल सिरे
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// सिंपल लाइन
canvas.drawLine(lineStartX, lineStartY, lineEndX, lineEndY, paint);
// और शेप्स उदाहरण
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(200, 200, 50, paint); // भरा सर्कल
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4f);
canvas.drawRect(100, 400, 300, 500, paint); // आउटलाइन रेक्ट
// टेक्स्ट ड्रा
paint.setColor(Color.BLACK);
paint.setTextSize(40f);
canvas.drawText("Canvas ड्राइंग", 50, 600, paint);
}
// लाइन एंडपॉइंट्स अपडेट करने के लिए मेथड
public void updateLine(float startX, float startY, float endX, float endY) {
this.lineStartX = startX;
this.lineStartY = startY;
this.lineEndX = endX;
this.lineEndY = endY;
invalidate(); // रीड्रॉ ट्रिगर करें
}
}
चरण 3: Layout में कस्टम व्यू उपयोग करें (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<com.example.drawlinedemo.DrawView
android:id="@+id/drawView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F5F5F5" />
<Button
android:id="@+id/btnChangeLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="32dp"
android:text="लाइन स्थिति बदलें"
android:padding="12dp 24dp" />
</RelativeLayout>
चरण 4: MainActivity.java — कस्टम व्यू के साथ इंटरैक्ट करें
package com.example.drawlinedemo;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
private DrawView drawView;
private Button btnChangeLine;
private Random random = new Random();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawView = findViewById(R.id.drawView);
btnChangeLine = findViewById(R.id.btnChangeLine);
btnChangeLine.setOnClickListener(v -> {
int width = drawView.getWidth();
int height = drawView.getHeight();
if (width > 0 && height > 0) {
// रैंडम नई पोजीशन
float margin = 50;
float newStartX = margin + random.nextFloat() * (width - 2 * margin);
float newStartY = margin + random.nextFloat() * (height - 2 * margin);
float newEndX = margin + random.nextFloat() * (width - 2 * margin);
float newEndY = margin + random.nextFloat() * (height - 2 * margin);
drawView.updateLine(newStartX, newStartY, newEndX, newEndY);
}
});
}
}
चरण 5: विधि 2 — Bitmap पर ड्रा करके ImageView में सेट करना (मूल लेख का तरीका)
नोट: यह तरीका **स्टेटिक इमेज जेनरेट करने** के लिए ठीक है, लेकिन **एनिमेशन/इंटरैक्शन के लिए अनुपयुक्त** — हर फ्रेम नया Bitmap बनाना पड़ता है।
// MainActivity2.java में
Button btnDraw = findViewById(R.id.btnDraw);
ImageView ivCanvas = findViewById(R.id.ivCanvas);
btnDraw.setOnClickListener(v -> {
int width = 400;
int height = 400;
// 1. म्यूटेबल बिटमैप बनाएं
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
// 2. बिटमैप पर ड्रा करने वाला Canvas
Canvas canvas = new Canvas(bitmap);
// 3. बैकग्राउंड क्लियर करें (पारदर्शी या रंग)
canvas.drawColor(Color.WHITE);
// 4. Paint कॉन्फ़िगर करें
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(8f);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
// 5. लाइन ड्रा करें
float offset = 50;
canvas.drawLine(offset, height / 2f, width - offset, height / 2f, paint);
// 6. ImageView में सेट करें
ivCanvas.setImageBitmap(bitmap);
});
चरण 6: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.drawlinedemo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DrawLineDemo">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
🎨 Paint के मुख्य कॉन्फ़िगरेशन
| सेटिंग | मेथड | उदाहरण |
|---|---|---|
| रंग | setColor(int) | paint.setColor(Color.RED) |
| स्ट्रोक चौड़ाई | setStrokeWidth(float) | paint.setStrokeWidth(4f) |
| स्टाइल | setStyle(Style) | STROKE (आउटलाइन), FILL (भरा), FILL_AND_STROKE |
| एंटी-अलियासिंग | setAntiAlias(true) | किनारे स्मूथ — **हमेशा true रखें** |
| स्ट्रोक कैप | setStrokeCap(Cap) | ROUND, SQUARE, BUTT |
| स्ट्रोक जॉइन | setStrokeJoin(Join) | ROUND, BEVEL, MITER |
| पाथ इफेक्ट | setPathEffect() | डैश्ड लाइन: new DashPathEffect(new float[]{20,10}, 0) |
| शेडर (ग्रेडिएंट) | setShader() | new LinearGradient(...) |
📐 Canvas के मुख्य ड्राइंग मेथड्स
| मेथड | विवरण |
|---|---|
drawLine(x1, y1, x2, y2, paint) | लाइन |
drawRect(left, top, right, bottom, paint) | रेक्टेंगल |
drawCircle(cx, cy, radius, paint) | सर्कल |
drawOval(rectF, paint) | अंडाकार |
drawRoundRect(rectF, rx, ry, paint) | राउंडेड रेक्ट |
drawPath(path, paint) | कस्टम पाथ (बेज़ियर, आदि) |
drawText(text, x, y, paint) | टेक्स्ट |
drawBitmap(bitmap, x, y, paint) | इमेज ड्रा |
drawArc(rectF, startAngle, sweepAngle, useCenter, paint) | आर्क/पाई स्लाइस |
⚡ प्रदर्शन टिप्स
- ✅ **Paint ऑब्जेक्ट्स रीयूज़ करें** —
onDrawमें नए न बनाएं (GC प्रेशर)। - ✅ **कस्टम View + onDraw()** — इनवैलिडेशन ऑप्टिमाइज़्ड, GPU-अक्सेलरेटेड।
- ❌ **Bitmap + ImageView** हर फ्रेम में — धीमा, मेमोरी-हैवी।
- 🔄 कॉम्प्लेक्स एनिमेशन के लिए
ValueAnimator+invalidate()या **Compose Canvas** उपयोग करें।
सारांश
- 🎯 **सर्वोत्तम**: कस्टम
ViewमेंonDraw(Canvas)ओवरराइड करें — पुन: उपयोग योग्य, प्रदर्शनकारी, इंटरैक्टिव। - 🖼️ **Bitmap पर ड्रा करें** केवल जब: इमेज फाइल सेव करनी हो, शेयर करनी हो, या नोटिफिकेशन/विजेट में दिखानी हो।
- 🎨
Paintकॉन्फ़िगर करें: रंग, चौड़ाई, स्टाइल, एंटी-अलियास, कैप/जॉइन। - 📐
Canvasमेथड्स: लाइन, रेक्ट, सर्कल, पाथ, टेक्स्ट, बिटमैप। - 🚀 आधुनिक: **Jetpack Compose Canvas** — डिक्लेरेटिव, कोरूटीन-फ्रेंडली, कम बॉयलरप्लेट।