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

วิธีส่ง Drawable ระหว่าง Activity ใน Android ด้วย Kotlin

ตัวอย่างนี้สาธิตวิธี ส่งรูปภาพ (Drawable Resource ID) ระหว่าง Activity ผ่าน Intent Extra โดยส่งแค่ Integer Resource ID (ไม่ส่ง Bitmap โดยตรง)

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

Android Studio → New Project → Empty Activity

ขั้นตอนที่ 2: 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"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp"
        android:text="Pass Drawable Demo"
        android:textAlignment="center"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="24sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/btnSendDrawable"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Send Drawable to Next Activity" />

</RelativeLayout>

ขั้นตอนที่ 3: MainActivity.kt (Sender)

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "Send Drawable"

        val btnSend = findViewById

ขั้นตอนที่ 4: SecondActivity.kt (Receiver)

import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        title = "Received Drawable"

        val imageView = findViewById(R.id.ivReceived)

        // 🔑 รับ Resource ID กลับมา
        val drawableResId = intent.getIntExtra("drawable_res_id", -1)
        if (drawableResId != -1) {
            imageView.setImageResource(drawableResId)
        }
    }
}

ขั้นตอนที่ 5: Layout สำหรับ Activity ที่ 2 (activity_second.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"
    tools:context=".SecondActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="24dp"
        android:text="Second Activity - Received Image"
        android:textSize="18sp"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/ivReceived"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:scaleType="fitCenter" />

</RelativeLayout>

🔑 จุดสำคัญ: ทำไมส่ง Resource ID แทน Bitmap?

วิธี ข้อดี ข้อเสีย
Resource ID (Int) ✅ แนะนำ เล็ก, เร็ว, ไม่ทำ Parcelable Limit, รองรับ Vector Drawable ต้องอยู่ใน Package เดียวกัน (Same App)
Bitmap Parcelable ส่ง Bitmap จริงข้าม Process/App ได้ ใหญ่, ช้า, อาจเกิน Binder Limit (1MB), ต้อง Recycle
Byte Array ควบคุม Format/Quality เอง ใหญ่มาก, Slow, OOM Risk
Uri (Content Provider) Share ระหว่าง App ต่างกันได้ ซับซ้อน, ต้อง Implement ContentProvider

🔧 หากต้องส่ง Bitmap จริง (Cross-App หรือ Dynamic Image)

// Sender: Convert to ByteArray (Compress)
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
intent.putExtra("bitmap_bytes", stream.toByteArray())

// Receiver: Decode
val bytes = intent.getByteArrayExtra("bitmap_bytes")
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
imageView.setImageBitmap(bitmap)

📱 ใช้กับ Camera/Gallery (Uri)

// Sender (หลัง onActivityResult)
val imageUri = data?.data
intent.putExtra("image_uri", imageUri.toString())

// Receiver
val uriString = intent.getStringExtra("image_uri")
val uri = Uri.parse(uriString)
imageView.setImageURI(uri)
// หรือใช้ Glide/Coil: Glide.with(this).load(uri).into(imageView)

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

<activity android:name=".MainActivity">
    <intent-filter> ... </intent-filter>
</activity>
<activity android:name=".SecondActivity" />

ทดสอบ

  1. รันแอป → กดปุ่ม "Send Drawable"
  2. เปิด SecondActivity → แสดงไอคอน Launcher Foreground
  3. ลองเปลี่ยน Resource ID เป็น Drawable อื่นใน MainActivity