[Android] Activity, Intent

leeehaΒ·2022λ…„ 9μ›” 11일
1
post-thumbnail

좜처: https://sesac.seoul.kr/ (JetPackκ³Ό Kotlin을 ν™œμš©ν•œ Android App 개발 κ°•μ˜)

Component

  • μ»΄ν¬λ„ŒνŠΈλŠ” μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ κ΅¬μ„±μš”μ†Œλ₯Ό μ˜λ―Έν•˜λ©°, 클래슀둜 생성할 수 μžˆλ‹€.
  • μ»΄ν¬λ„ŒνŠΈλŠ” μ‹œμŠ€ν…œμ—μ„œ 생λͺ…μ£ΌκΈ°κ°€ κ΄€λ¦¬λœλ‹€. (λ°˜λ©΄μ—, 일반 클래슀의 생λͺ…μ£ΌκΈ°λŠ” 개발자 μ½”λ“œ μƒμ—μ„œ κ΄€λ¦¬λœλ‹€.)

  • μ•ˆλ“œλ‘œμ΄λ“œμ˜ 4λŒ€ μ»΄ν¬λ„ŒνŠΈ: Activity, Service, BroadcastReceiver, ContentProvider
    • μ•‘ν‹°λΉ„ν‹°: 화면을 좜λ ₯ν•˜κΈ° μœ„ν•œ μ»΄ν¬λ„ŒνŠΈ
    • μ„œλΉ„μŠ€: λ°±κ·ΈλΌμš΄λ“œ μž‘μ—…μ„ μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ μ»΄ν¬λ„ŒνŠΈ
    • λΈŒλ‘œλ“œμΊμŠ€νŠΈ λ¦¬μ‹œλ²„: 이벀트 λͺ¨λΈμ— μ˜ν•΄ μ‹€ν–‰λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ (μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ΄λ‚˜ μ‹œμŠ€ν…œμ— νŠΉμ • 상황이 λ°œμƒν–ˆμ„ λ•Œ ν•΄λ‹Ή 이벀트λ₯Ό μˆ˜μ‹ ν•˜λŠ” μ—­ν• )
    • 컨텐츠 ν”„λ‘œλ°”μ΄λ”: μ•± κ°„μ˜ 데이터 전달을 μœ„ν•œ μ»΄ν¬λ„ŒνŠΈ
  • μ–΄λ–€ μ»΄ν¬λ„ŒνŠΈλ₯Ό λͺ‡κ°œ μ‚¬μš©ν•˜μ—¬ 앱을 κ΅¬μ„±ν•˜λŠ”μ§€λŠ” 개발자의 선택사항이닀.


Intent

  • μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‹€ν–‰μ‹œν‚€κΈ° μœ„ν•΄ μ‹œμŠ€ν…œμ— λ„μš°λŠ” λ©”μ‹œμ§€
  • μ‹œμŠ€ν…œμ— μΈν…νŠΈ 정보λ₯Ό λ°œμƒμ‹œν‚€κ³ , μ‹œμŠ€ν…œμ—μ„œ ν•΄λ‹Ή 정보λ₯Ό 뢄석해 μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‹€ν–‰μ‹œν‚΄.
  • μ™ΈλΆ€ μ•±μ˜ μ»΄ν¬λ„ŒνŠΈλ„ μΈν…νŠΈμ— μ˜ν•΄ 싀행됨.


Activity

MainActivity와 같은 디렉토리에 Empty Activityλ₯Ό μΆ”κ°€ν•˜λ©΄, AndroidManifest.xml νŒŒμΌμ— μžλ™μœΌλ‘œ μƒˆλ‘œμš΄ μ•‘ν‹°λΉ„ν‹°κ°€ λ“±λ‘λœλ‹€. μ‹œμŠ€ν…œμ—μ„œ 생λͺ…μ£ΌκΈ°κ°€ κ΄€λ¦¬λ˜λŠ” μ»΄ν¬λ„ŒνŠΈλ“€μ€ AndroidManifest.xml νŒŒμΌμ— κΌ­ λ“±λ‘ν•΄μ€˜μ•Ό ν•œλ‹€.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorial.c40" >

    <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.AndroidLab" >
        <activity
            android:name=".DetailActivity"
            android:exported="false" />
        <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>
package com.tutorial.c40

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)

        val button = findViewById<Button>(R.id.button)
        button.setOnClickListener {
            val intent = Intent(this, DetailActivity::class.java)
            startActivity(intent)
        }
    }
}


Extra Data

  • Intent둜 μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‹€ν–‰μ‹œν‚€λ©΄μ„œ 데이터λ₯Ό μ „λ‹¬ν•˜λŠ” 방법
  • μΈν…νŠΈμ— 데이터λ₯Ό λ‹΄μ•„μ„œ 전달함.

// μΈν…νŠΈμ— 데이터 전달
public Intent putExtra(String name, CharSequence value)

// μΈν…νŠΈλ₯Ό 톡해 데이터 νšλ“ 
public int getIntExtra(String name, int defaultValue)
public String getStringExtra(String name)
public double getDoubleExtra(String name, double defaultValue) 

예제

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
</ListView>
package com.tutorial.c40

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

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val listView = findViewById<ListView>(R.id.main_list)
        val data = arrayOf("android", "kotlin", "jetpack")
        val adapter = ArrayAdapter(
            this,
            android.R.layout.simple_list_item_1,
            data
        )
        listView.adapter = adapter

        listView.setOnItemClickListener { adapterView, view, i, l ->
            val intent = Intent(this, DetailActivity::class.java)
            intent.putExtra("id", i)
            intent.putExtra("title", data[i])
            startActivity(intent)
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".DetailActivity">

    <TextView
        android:id="@+id/resultView"
        android:textSize="30sp"
        android:textStyle="bold"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>
package com.tutorial.c40

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

class DetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail)

        val id = intent.getIntExtra("id", 0)
        val title = intent.getStringExtra("title")

        val resultView = findViewById<TextView>(R.id.resultView)
        resultView.text = "id: $id, title: $title"
    }
}


Activity Result

μΈν…νŠΈλ‘œ μ•‘ν‹°λΉ„ν‹°λ₯Ό μ‹€ν–‰μ‹œν‚€κ³  κ²°κ³Όλ₯Ό 돌렀 λ°›λŠ” 방법은 두가지가 μžˆλ‹€.

  • startActivityForResult() ν•¨μˆ˜ (deprecated)
  • ActivityResultLauncher, registerForActivityResult() ν•¨μˆ˜

startActivityForResult (deprecated)

public void startActivityForResult(Intent intent, int requestCode) 
val intent = Intent(this, DetailActivity::class.java)
startActivityForResult(intent, 10) 

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
	super.onActivityResult(requestCode, resultCode, data)
    if(requestCode == 10 && resultCode == RESULT_OK) {
    	// ... 
    }
}

registerForActivityResult

val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
	// ... 
}

val intent = Intent(this, DetailActivity::class.java)
resultLauncher.launch(intent) 
intent.putExtra("result", "hello $id")
setResult(RESULT_OK, intent)
finish() 

예제

MainActivity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/resultView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:text="startActivityForResult()" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:text="ActivityResultLauncher" />

</LinearLayout>
package com.tutorial.c41

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    lateinit var resultView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val btn1 = findViewById<Button>(R.id.btn1)
        val btn2 = findViewById<Button>(R.id.btn2)
        resultView = findViewById(R.id.resultView)

		// 방법 1) startActivityForResult() ν•¨μˆ˜
        btn1.setOnClickListener {
            val intent = Intent(this, DetailActivity::class.java)
            intent.putExtra("id", "first") // λΆ€κ°€ 데이터 전달 
            startActivityForResult(intent, 10)
        }

		// 방법 2) registerForActivityResult() ν•¨μˆ˜
        val resultLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()){
            resultView.text = "result: ${it.data?.getStringExtra("result")}"
        }

        btn2.setOnClickListener {
            val intent = Intent(this, DetailActivity::class.java)
            intent.putExtra("id", "second") // λΆ€κ°€ 데이터 전달 
            resultLauncher.launch(intent)
        }
    }

	// 방법 1에 λŒ€ν•œ 처리 
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(requestCode == 10 && resultCode == RESULT_OK){
            val result: String? = data?.getStringExtra("result") // λΆ€κ°€ 데이터 λ°›κΈ° 
            resultView.text = "result : $result"
        }
    }
}

DetailActivity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context=".DetailActivity">

    <Button
        android:id="@+id/finishButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="finish"/>

</LinearLayout>
package com.tutorial.c41

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

class DetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail)

        val id = intent.getStringExtra("id") // λΆ€κ°€ 데이터 λ°›κΈ° 
        val button = findViewById<Button>(R.id.finishButton)
        
        // 방법 2에 λŒ€ν•œ 처리 
        button.setOnClickListener {
            intent.putExtra("result", "hello $id")
            setResult(RESULT_OK, intent)
            finish()
        }
    }
}

Implicit Intent

μΈν…νŠΈμ— μ˜ν•΄ μ‹€ν–‰λ˜λŠ” "μ»΄ν¬λ„ŒνŠΈμ˜ 정보"둜 μ–΄λ–€ 것을 μ΄μš©ν•˜λƒμ— 따라 μ•„λž˜ λ‘κ°€μ§€λ‘œ ꡬ뢄됨.

  • λͺ…μ‹œμ  μΈν…νŠΈ: 클래슀 νƒ€μž… μ°Έμ‘° 정보λ₯Ό ν™œμš©ν•œ μΈν…νŠΈ
  • μ•”μ‹œμ  μΈν…νŠΈ: μΈν…νŠΈ ν•„ν„° 정보λ₯Ό ν™œμš©ν•œ μΈν…νŠΈ

Intent Filter

λͺ…μ‹œμ  μΈν…νŠΈμ—λŠ” 클래슀λͺ… 정보λ₯Ό λ‹΄μ•„μ„œ μ‹œμŠ€ν…œμ— μΈν…νŠΈλ₯Ό λ°œμƒμ‹œν‚¨λ‹€. 그러면 μ‹œμŠ€ν…œμ€ μΈν…νŠΈμ— λ‹΄κΈ΄ 클래슀λͺ… 정보λ₯Ό 보고 ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‹€ν–‰μ‹œν‚¨λ‹€. μ΄λŸ¬ν•œ ꡬ쑰가 κ°€λŠ₯ν•˜λ €λ©΄, μΈν…νŠΈμ˜ μ‹€ν–‰ λŒ€μƒμ΄ λ˜λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ μ•ˆλ“œλ‘œμ΄λ“œ 메인 ν™˜κ²½ 파일인 λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— λ“±λ‘λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€. activity νƒœκ·Έμ˜ ν•„μˆ˜ 속성인 name에 클래슀λͺ… 정보λ₯Ό μž‘μ„±ν•˜λ©΄ λœλ‹€.

ν”„λ‘œκ·Έλž¨μ΄ λ™μž‘ν•˜λ‹€κ°€ μ–΄λŠ μˆœκ°„μ— μΈν…νŠΈκ°€ λ°œμƒν•˜λ©΄, ν•΄λ‹Ή μΈν…νŠΈ 정보와 μ‹œμŠ€ν…œμ΄ λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ—μ„œ μΈμ§€ν•œ μ»΄ν¬λ„ŒνŠΈ 정보λ₯Ό μ„œλ‘œ λΉ„κ΅ν•˜μ—¬ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰μ‹œν‚¨λ‹€.

이처럼, λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— "클래슀λͺ… μ •λ³΄λ§Œ" λ“±λ‘ν•˜λ©΄ ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈλŠ” λͺ…μ‹œμ  μΈν…νŠΈμ— μ˜ν•΄μ„œλ§Œ μ‹€ν–‰λœλ‹€. 그리고 λͺ…μ‹œμ  μΈν…νŠΈλŠ” ν•˜λ‚˜μ˜ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ 내에 μžˆλŠ” μ„œλ‘œ λ‹€λ₯Έ μ»΄ν¬λ„ŒνŠΈ κ°„μ—λŠ” 이용 κ°€λŠ₯ν•˜μ§€λ§Œ, μ™ΈλΆ€ 앱에 μžˆλŠ” μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” 이용 λΆˆκ°€λŠ₯ν•˜λ‹€.

μ•”μ‹œμ  μΈν…νŠΈλŠ” μΈν…νŠΈ ν•„ν„° 정보λ₯Ό μ΄μš©ν•œλ‹€. 즉, λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— μ»΄ν¬λ„ŒνŠΈ 정보λ₯Ό 등둝할 λ•Œ 클래슀λͺ…λΏλ§Œ μ•„λ‹ˆλΌ μΈν…νŠΈ 필터에 λ‹€λ₯Έ 정보도 λ“±λ‘ν•΄μ€˜μ•Ό μ•”μ‹œμ  μΈν…νŠΈλ‘œ ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‹€ν–‰μ‹œν‚¬ 수 μžˆλ‹€. 이처럼 μΈν…νŠΈ ν•„ν„° 정보λ₯Ό μ΄μš©ν•˜λ©΄, λ‹€λ₯Έ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 클래슀λͺ… 정보λ₯Ό λͺ¨λ₯΄λ”라도 μ•”μ‹œμ  μΈν…νŠΈλ₯Ό 톡해 μ™ΈλΆ€ μ•±μ˜ μ»΄ν¬λ„ŒνŠΈλ„ μ‹€ν–‰μ‹œν‚¬ 수 μžˆλ‹€.

μš°λ¦¬κ°€ μ•ˆλ“œλ‘œμ΄λ“œ μŠ€νŠœλ””μ˜€μ—μ„œ 앱을 λ§Œλ“€λ©΄ λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— μžλ™μœΌλ‘œ λ‹€μŒκ³Ό 같은 λ‚΄μš©μ΄ λ“±λ‘λœλ‹€. 즉, 우리의 앱도 μ™ΈλΆ€ 앱인 런처 μ•±μ—μ„œ μ•„μ΄μ½˜μ„ ν΄λ¦­ν•˜λ©΄ μΈν…νŠΈκ°€ λ°œμƒν•˜μ—¬ 싀행이 λ˜λŠ” 원리이기 λ•Œλ¬Έμ—, μΈν…νŠΈ 필터에 μ•„λž˜μ™€ 같은 λ‚΄μš©μ΄ λ“±λ‘λ˜μ–΄ μžˆλŠ” 것이닀.

  • <action> : μ»΄ν¬λ„ŒνŠΈμ˜ λŠ₯λ ₯을 ν‘œν˜„ν•˜λŠ” λ¬Έμžμ—΄
  • <category> : μ»΄ν¬λ„ŒνŠΈκ°€ μ–΄λŠ 범주에 ν¬ν•¨λ˜μ–΄μ•Ό ν•˜λŠ”μ§€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ¬Έμžμ—΄
  • <data> : μ»΄ν¬λ„ŒνŠΈμ—μ„œ ν•„μš”ν•œ λ°μ΄ν„°μ˜ 정보

κ²°κ΅­ μœ„μ˜ μ½”λ“œμ—μ„œ μ•”μ‹œμ  μΈν…νŠΈμ—λŠ” 클래슀λͺ… 정보가 μ—†μ§€λ§Œ, μΈν…νŠΈ 필터에 μ˜ν•΄ μ‹œμŠ€ν…œμ— λ“±λ‘λ˜μ–΄ μžˆλŠ” μ»΄ν¬λ„ŒνŠΈ μ€‘μ—μ„œ μ•‘μ…˜ λ¬Έμžμ—΄μ΄ "ACTION_EDIT"이고 데이터 정보가 "http"둜 λ˜μ–΄ μžˆλŠ” μ»΄ν¬λ„ŒνŠΈκ°€ μ‹€ν–‰λœλ‹€.

예제

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tutorial.c42">

    <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.AndroidLab">
        <activity
            android:name=".DetailActivity"
            android:exported="false">
            <intent-filter>
                <action android:name="ACTION_DETAIL"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="http"/>
            </intent-filter>
        </activity>
        <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>

MainActivity

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="DetailActivity"
        android:textAllCaps="false"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
package com.tutorial.c42

import android.content.Intent
import android.net.Uri
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)

        val button = findViewById<Button>(R.id.button)
        button.setOnClickListener {
        	// μ—¬κΈ°μ„œ μ§€μ •ν•œ μΈν…νŠΈ ν•„ν„° 정보와 μΌμΉ˜ν•˜λŠ” μ•‘ν‹°λΉ„ν‹°λ₯Ό μ‹€ν–‰ν•œλ‹€. (μ•”μ‹œμ  μΈν…νŠΈ)
            val intent = Intent() 
            intent.action = "ACTION_DETAIL"
            intent.data = Uri.parse("http://www.google.com")
            startActivity(intent)
        }
    }
}

DetailActivity

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DetailActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="I am DetailActivity"
        android:textStyle="bold"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
package com.tutorial.c42

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

class DetailActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detail)
    }
}
profile
μŠ΅κ΄€μ΄ 될 λ•ŒκΉŒμ§€ πŸ“

0개의 λŒ“κΈ€