오늘은 Fragment 에서 Activity 를 실행시키고 결과를 받아보도록 하겠습니다.
결과는 registerForActivityResult() 메소드를 사용해 등록한 ActivityResultCallback 에서 받도록 하겠습니다.
registerForActivityResult() 에 대한 정보는 아래 링크의 게시글을 확인해주세요.
https://stickode.tistory.com/187
계획은 메인 액티비티에서 프래그먼트를 2개 만들고 하단에 있는 버튼으로 그 프래그먼트들을 교체할 수 있게 만들겠습니다.
그리고 현재 켜져있는 프레그먼트에서 사용자 입력을 받기 위한 액티비티를 켜고 registerForActivityResult() 를 통해 프레그먼트에서 데이터를 받도록 구현해보겠습니다.
먼저 메인 레이아웃 파일입니다.
activity_main.xml
<?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"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/mainFragmentContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/mainFragmentChangeButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="프래그먼트 교체 버튼"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
프레그먼트가 들어갈 mainFragmentContainer 와 교체를 위한 버튼인 mainFragmentChangeButton 를 두었습니다.
다음으로 교체 될 프래그먼트의 레이아웃입니다.
fragment_replace.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<Button
android:id="@+id/replaceTitleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="제목"
android:textSize="30sp" />
</LinearLayout>
액티비티를 실행하고 받은 결과를 표시할 replaceTitleButton 하나만 두도록 하겠습니다.
마지막으로 사용자 입력을 받기 위한 액티비티의 레이아웃 입니다.
activity_sub.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/subEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/subSummitButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="프래그먼트로 보내기" />
</LinearLayout>
값을 입력받는 에딧텍스트와 결과를 전송할 버튼으로 이루어져있습니다.
먼저 SubActivity 클래스를 만들고 manifests 에 등록해주세요.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tstory1">
<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.Tstory1">
<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>
<!-- 여기에 SubActivity 를 추가 -->
<activity android:name=".SubActivity" />
</application>
</manifest>
다음으로 서브 클래스 java 코드입니다.
SubActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
public class SubActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub);
EditText editText = findViewById(R.id.subEditText);
Button summitButton = findViewById(R.id.subSummitButton);
summitButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("key", editText.getText());
setResult(RESULT_OK, intent);
finish();
}
});
}
}
제출 버튼이랑 에딧텍스트를 findViewById 를 통해 찾습니다.
그리고 제출 버튼이 눌리면 인텐트에 에딧텍스트에 들어있는 값을 인텐트에 넣고, setResult() 로 결과를 설정하고, 액티비티를 종료합니다.
다음으로 교체 프래그먼트입니다.
ReplaceFragment.java
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
public class ReplaceFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_replace, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle bundle = getArguments();
if (bundle == null) return;
String title = bundle.getString("key");
Button button = view.findViewById(R.id.replaceTitleButton);
button.setText(title);
ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == AppCompatActivity.RESULT_OK) {
Intent data = result.getData();
CharSequence text = data.getCharSequenceExtra("key");
button.setText(text);
}
}
}
);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
activityResultLauncher.launch(new Intent(requireActivity(), SubActivity.class));
}
});
}
}
onCreateView 에서 레이아웃을 부풀(?)립니다.
그 후 onViewCreated 에서 MainActivity 에서 전달받은(아래 MainActivity 에서 설명할 예정) 프래그먼트의 제목을 버튼에 셋팅하도록 합니다.
그리고 오늘의 주인공인 registerForActivityResult() 를 사용해서 콜백을 등록합니다.
콜백이 RESULT_OK 면 SubActivity 에서 넣은 에딧텍스트 값을 가져와서 Button 에 넣습니다.
마지막으로 button 을 누르면 사용자 입력을 받을 SubActivity 를 실행시킵니다.
마지막으로 메인 액티비티입니다.
MainActivity.java
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity {
boolean isTrue;
ReplaceFragment trueFragment, falseFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.mainFragmentChangeButton);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isTrue) {
if (trueFragment == null) {
trueFragment = new ReplaceFragment();
}
replaceFragment(trueFragment, "true");
} else {
if (falseFragment == null) {
falseFragment = new ReplaceFragment();
}
replaceFragment(falseFragment, "false");
}
}
});
button.performClick();
}
void replaceFragment(Fragment fragment, String name) {
isTrue = !isTrue;
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment beforeFragment = getSupportFragmentManager().getPrimaryNavigationFragment();
if (beforeFragment != null) {
transaction.hide(beforeFragment);
}
if (!getSupportFragmentManager().getFragments().contains(fragment)) {
Bundle bundle = new Bundle();
bundle.putString("key", name);
fragment.setArguments(bundle);
transaction.add(R.id.mainFragmentContainer, fragment);
}
transaction
.setPrimaryNavigationFragment(fragment)
.show(fragment).commit();
}
}
프래그먼트 교체용 스위치로 isTrue 라는 멤버 변수를 사용합니다.
교체하기 위한 두개의 프래그먼트를 멤버 변수에 선언합니다.
onCreate 에서 프래그먼트 교체 버튼을 찾아서 버튼 클릭 로직을 작성합니다.
클릭하면 isTrue 에 따라 trueFragment, falseFragment 를 replaceFragement() 의 인자로 넣어줍니다.
replaceFragement() 는 프래그먼트를 교체해주는 메소드입니다.
교체하기전에 띄워져있던 프레그먼트가 있으면 getPrimaryNavigationFragment() 로 가져와 숨기고, 새로 전달받은 프래그먼트를 보여줍니다.
새로 전달받은 프래그먼트가 FragmentManager 에 추가가 안되어 있으면 프래그먼트에 이름을 번들로 넣고(아까 위에서 말한 부분) FragmentManager 에 추가해줍니다.
마지막으로 보여줄 프래그먼트를 setPrimaryNavigationFragment 에 넣고 액티비티에 띄웁니다.
실행 영상입니다.
'안드로이드 자바' 카테고리의 다른 글
[JAVA][Android] 핸들러를 사용해 원형프로그래스바를 실행하고, 종료시 토스트 메시지 띄우기 (0) | 2022.01.21 |
---|---|
[JAVA][Android] Textview의 텍스트 생략 기호(...) 사용 또는 텍스트 흐름 효과주기 (0) | 2022.01.19 |
[JAVA][Android] 나의 현재 위치 찾기 (0) | 2022.01.12 |
[JAVA][Android] Youtube API 사용법 (0) | 2022.01.07 |
[JAVA][Android] 녹음 기능 만들기 (0) | 2021.12.31 |