Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีวาดเส้นใน Android ด้วย Canvas

ภาพรวม

ตัวอย่างนี้สาธิตการวาดเส้น (Draw Line) บน Canvas แล้วนำไปแสดงใน ImageView

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

เปิด Android Studio → File → New Project และกรอกข้อมูลที่จำเป็น

ขั้นตอนที่ 2: เลย์เอาต์ (res/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:id="@+id/relativeLayout"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Draw Line"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="70dp" />

</RelativeLayout>

ขั้นตอนที่ 3: โค้ดหลัก (src/MainActivity.java)

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {
    Context context;
    Resources resources;
    RelativeLayout relativeLayout;
    Button button;
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        context = getApplicationContext();
        resources = getResources();
        relativeLayout = findViewById(R.id.relativeLayout);
        button = findViewById(R.id.button);
        imageView = findViewById(R.id.imageView);

        button.setOnClickListener(view -> {
            // สร้าง Bitmap ขนาด 400x400 (ปรับจาก 10x700 เดิมที่ผิด)
            Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            
            // พื้นหลังโปร่งใส (หรือสีพื้น)
            canvas.drawColor(Color.TRANSPARENT);
            
            // ตั้งค่า Paint
            Paint paint = new Paint();
            paint.setColor(Color.RED);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(8);
            paint.setAntiAlias(true); // ขอบเรียบ
            paint.setStrokeCap(Paint.Cap.ROUND); // ปลายเส้นกลม

            // วาดเส้นตรงแนวนอนตรงกลาง
            int offset = 50;
            int centerY = canvas.getHeight() / 2;
            canvas.drawLine(
                offset, centerY, 
                canvas.getWidth() - offset, centerY, 
                paint
            );

            // วาดเส้นทแยงมุม (ตัวอย่างเพิ่มเติม)
            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(4);
            canvas.drawLine(0, 0, canvas.getWidth(), canvas.getHeight(), paint);

            // วาดวงกลม (ตัวอย่างเพิ่มเติม)
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(Color.GREEN);
            canvas.drawCircle(canvas.getWidth() / 2f, canvas.getHeight() / 2f, 50, paint);

            imageView.setImageBitmap(bitmap);
        });
    }
}

ขั้นตอนที่ 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">

    <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/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

การทดสอบ

รันแอป กดปุ่ม "Draw Line" จะวาดเส้นและรูปทรงต่างๆ แสดงใน ImageView

วิธีวาดเส้นใน Android ด้วย Canvas

Canvas และ Paint คำสั่งหลัก

Paint Settings

Methodคำอธิบาย
setColor(int color)สีเส้น/เติม
setStyle(Style)STROKE (ขอบ), FILL (เติม), FILL_AND_STROKE
setStrokeWidth(float)ความหนาเส้น (px)
setAntiAlias(boolean)Anti-aliasing ขอบเรียบ
setStrokeCap(Cap)BUTT, ROUND, SQUARE ปลายเส้น
setStrokeJoin(Join)MITER, ROUND, BEVEL มุมเชื่อม
setPathEffect(PathEffect)DashPathEffect, CornerPathEffect ฯลฯ
setShader(Shader)LinearGradient, RadialGradient, SweepGradient

Canvas Drawing Methods

Methodคำอธิบาย
drawLine(x1, y1, x2, y2, paint)เส้นตรง
drawRect(left, top, right, bottom, paint)สี่เหลี่ยม
drawCircle(cx, cy, radius, paint)วงกลม
drawOval(rectF, paint)วงรี
drawArc(rectF, startAngle, sweepAngle, useCenter, paint)โค้ง/วงกลมไม่เต็ม
drawPath(path, paint)เส้นทางซับซ้อน
drawText(text, x, y, paint)ข้อความ
drawBitmap(bitmap, x, y, paint)ภาพ

แนวทางปฏิบัติที่ดี (Best Practices)

1. สร้าง Paint Object นอก Loop (Reuse)

// ❌ ไม่ดี - สร้างใหม่ทุก Frame
onDraw() {
    Paint p = new Paint();
    p.setColor(Color.RED);
    canvas.drawLine(0, 0, 100, 100, p);
}

// ✅ ดี - สร้างครั้งเดียวเป็น Field
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
{ paint.setColor(Color.RED); paint.setStrokeWidth(4); }

onDraw() {
    canvas.drawLine(0, 0, 100, 100, paint);
}

2. ใช้ Custom View แทน ImageView + Bitmap

public class DrawingView extends View {
    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public DrawingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(8);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(50, getHeight()/2f, getWidth()-50, getHeight()/2f, paint);
    }
}

// ใน XML
<com.example.DrawingView
    android:layout_width="match_parent"
    android:layout_height="200dp" />

3. Hardware Acceleration

Canvas operations ส่วนใหญ่รองรับ Hardware Acceleration แต่บางอย่างไม่รองรับ (เช่น Path.addArc บางกรณี) ต้องทดสอบ