일반적으로 앱들은 하나의 앱으로 되어있지 않고, 여러 페이지로 되어있다. 즉 여러가지 액티비티를 두고, 액티비티를 전환하는 것이다. 액티비티를 추가 하기 위해서 안드로이드 프로젝트 "app" 우클릭 - New - Activity - Empty Activity를 선택하여 새로운 액티비티를 추가해 준다.
액티비티를 이렇게 추가해 주면, AndroidManifest에 새로 추가한 액티비티의 정보가 들어가 있을것이다. 여기서 각자 만들고자 하는 예제에 따라 추가적인 속성을 부여해 준다. 필자같은 경우 , Dialog 테마의 액티비티를 생성해 주었고, 액티비티의 제목에 해당하는 label속성은 Menu Activity로 지정하였다.
<activity
android:name=".MenuActivity"
android:exported="false"
android:theme="@style/Theme.AppCompat.Dialog"
android:label="Menu Activity"></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>
<activity> 태그는 기본적으로, 생성된 액티비티에 대한 정보를 가지고 잇으며, 새로운 액티비티를 만든다면, Manifest파일에 새 액티비티 정보를 넣어주어야 한다. 예시코드를 작성해 보자. 상황 가정은 메인 액티비티에서 버튼을 누르면, 새로운 Dialog액티비티를 띄운 후 값을 전달받는다는 가정이다.
우선 MainActivity에서 새로운 액티비티를 열고 다시 MainActivity로 돌아가도록 코드를 작성한다.
< activity_menu.xml >
<?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=".MenuActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="156dp"
android:layout_marginTop="340dp"
android:text="Back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
< MenuActivity.java >
package com.example.sampleintent;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MenuActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.putExtra("name","mike");
setResult(RESULT_OK,intent);
finish();
}
});
}
}
이 예시에서는 Intent객체를 만든 후 setResult() 메소드를 호출한다.
putExtra(String name, (Other Datatypes) value)에는 Intent 객체에 데이터를 추가하는 메소드이다, 기본적으로 "key" : "value" 타입으로 데이터가 저장되며, 위 코드를 해석해 보면, "name"이라는 키값으로 "mike"라는 문자열에 접근할 수 있는 데이터를 intent에 추가하는 것이다.
setResult(Result_Code, Intent intent) 같은 경우에는 두가지 매개변수를 받는다. Result_Code는 응답코드를 의미한다. 이는 밑에서 자세히 볼것이다
이번에는 MainActivity에서 버튼을 클릭했을때 메뉴 화면을 띄우고 반환 받은 값을 처리하는 코드를 작성해 보자.
ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if(result.getResultCode() == RESULT_OK){
Intent intent = result.getData();
String str = intent.getStringExtra("name");
Toast.makeText(MainActivity.this,str,Toast.LENGTH_SHORT).show();
}
}
}
);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button2);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,MenuActivity.class);
resultLauncher.launch(intent);
}
});
}
기본적으로 새로운 액티비티를 호출할때 startActivity를 사용한다. 하지만 startActivity는 말 그대로 액티비티를 띄울수만 있는 메소드이다. 기존에는 startActivityForResult라는 메소드를 이용해서 새로 띄운 액티비티의 응답 데이터를 통해 상호작용 하곤 하였다. 하지만 startActivityForResult는 Deprecated되었다. 대신 ActivityResultLauncher<Intent> 객체를 사용해야한다.
startActivityForResult와 ActivityResultLauncher의 차이점을 살펴보자
- startActivityForResult
- onActivityResult메소드를 Override해서 처리, 이 onActivityResult를 통해 여러개의 액티비티 호출에 대한 결과값을 대응해 줄 수 있었다.
- 일반적으로 Activity.RESULT_OK상수를 통해서 응답코드를 반환하지만, 사용자가 응답코드를 지정하여 사용할 수 도 있다.
기본적인 startActivityForResult의 형태는 아래와 같다
private final int RESULT_CODE = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.button2);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,MenuActivity.class);
startActivityForResult(intent, RESULT_CODE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){//처리문}
if(resultCode == RESULT_CODE){//처리문}
}
- ActivityResultLauncher
- 호출할 각 Activity별로 ActivityResultLauncher 객체를 만들어 주어야 한다
- registerForActivityResult() 를 사용해서 ActivityResultContract 및 ActivityResultCallback을 가져와 다른 액티비티에서 실행하는데 사용할 ActivityResultLauncher를 반환한다.
- startActivityForResult와 달리 각 Activity별로 생성해 주어야 하므로, 응답코드를 따로 만들어 처리할 필요도 없고 할수도 없다.
위 코드를 보면 ActivityResultLauncher타입 객체의 lauch()메소드에 intent 객체를 넘김으로서 새 액티비티를 생성하는것을 볼 수 있다.
registerForActivityResult() 메소드를 보자. 이 메소드는 기본적으로 ActivityResultLauncher 객체를 반환하며, ActivityResultContracts.StartActivityForResult() 인스턴스와 ActivityResult타입 객체를 받아 결과값을 처리할 수 있는 콜백함수가 있다. 콜백함수에는 Intent타입을 반환하는 getData()를 이용해 Intent객체를 반환받은 후, 아까 새로운 레이아웃에 넣었던 String값을 getStringExtra()메소드로 받아온다.
예시의 결과는 아래와 같다.
'Android' 카테고리의 다른 글
[Android] 앱 내에서 다크모드 비활성화하기 (0) | 2022.05.09 |
---|---|
[Android] LayoutInflator사용해 보기 (0) | 2022.04.08 |
[Android] Inflation이란? (0) | 2022.04.08 |
[Android] Progressbar 사용하기 (0) | 2022.04.07 |
[Android] Snackbar사용하기 (0) | 2022.04.07 |