프래그먼트간 데이터전달에 result API를 이용하는 방법이 있다는것을 발견하고 시도하는데
잘안돼서 질문드립니다.
앱설명을 드리자면 싱글 액티비티로 도전중입니다.
메인화면(액티비티)가 바텀내비게이션으로 이루어져 있습니다. 3개의 메뉴가 있고 그중 1개 메뉴(프래그먼트)만 만들어놓은상태입니다.
메뉴 이동후 바뀐 화면에서 버튼을누르면 다이얼로그프래그먼트 창이 뜹니다.
여기서 데이터를 선택후 창을 닫으면, 창 종료와 함께 선택한 데이터를 전달하면서
또 다른 프래그먼트로 전환하게끔 하는것이 목표입니다.
데이터를 전달 없이 창 종료후 프래그먼트 전환 테스트에서는 잘 됐는데
데이터를 전달하기 시작하고부터 자꾸 앱이 튕기네요.
전환한 프래그먼트에서 전달된 데이터가 null이라고 뜨는게 문제입니다..
하지만 왜 그런지 잘모르겠습니다. 디버깅결과 전달하기까지는 Bundle에 데이터가 들어가있는것을 확인했습
니다. 아마 받는쪽에서 null이 되는것 같습니다.
창 종료후 화면전환은 액티비티에서 전환 메소드를 구현해서 프래그먼트에서 호출하는 방식으로 햇습니다.
무엇이 문제일까요.. 화면을 전환하는 과정(액티비티의 전환메소드를 호출할때)에서 데이터를 셋팅하는게
문제인것같은데 잘 캐치를 못하겠습니다..무엇이 문제일까요..
* result API라는 프래그먼트간 데이터 전달하는 것이 문서에 나와있어서 사용해보고 있는데 너무 복잡한 방법이라면,, 혹은 비추천한다면 말씀해주세요
MainActivity.java
public class MainActivity extends AppCompatActivity {
BottomNavigationView bottomNav;
FragmentManager fm;
FragmentTransaction transaction;
Fragment curFrag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNav = findViewById(R.id.bottom_nav);
bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
fm = getSupportFragmentManager();
transaction = fm.beginTransaction();
curFrag = fm.getPrimaryNavigationFragment();
String tag = String.valueOf(item.getItemId());
int id = item.getItemId();
if(curFrag != null) {
transaction.hide(curFrag);
}
Fragment fragment = fm.findFragmentByTag(tag);
if(fragment == null) { // 일단 메뉴 하나만 구현
if(id == R.id.list)
fragment = new WorkoutListFragment();
transaction.add(R.id.content_layout, fragment);
}
else {
transaction.show(fragment);
}
transaction.setPrimaryNavigationFragment(fragment);
transaction.setReorderingAllowed(true);
transaction.commitNow();
return true;
}
});
}
public void onFragmentChanged() {
transaction = fm.beginTransaction();
String tag = "WriteRoutine";
curFrag = fm.getPrimaryNavigationFragment();
if (curFrag != null) {
transaction.hide(curFrag);
}
Fragment fragment = fm.findFragmentByTag(tag);
if (fragment == null) {
fragment = new WriteRoutineFragment();
transaction.add(R.id.content_layout, fragment, tag);
} else {
transaction.show(fragment);
}
transaction.setReorderingAllowed(true);
transaction.commitNow();
}
}
BodyPartDialogFragment.java
public class BodyPartDialogFragment extends DialogFragment {
Button startBtn;
ArrayList<String> bodypart_strData; // 선택된 부위 보낼 문자열 인스턴스
String[] dialog_str_list;
int selectedNum; // 선택된 부위 개수
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_body_part_dialog, null);
// 추 가 (저장일지 추가)
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedNum == 0){ // 하나도 선택되지 않았을때
Toast.makeText(getContext(), "부위를 선택해 주세요", Toast.LENGTH_SHORT).show();
}
else {
MainActivity activity = (MainActivity) getActivity();
Bundle result = new Bundle();
result.putStringArrayList("title", bodypart_strData);
getParentFragmentManager().setFragmentResult("result", result);
activity.onFragmentChanged();
dismiss();
}
}
});
return view;
}
}
WriteRoutineFragment.java
public class WriteRoutineFragment extends Fragment {
TextView title;
List<String> titleData;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getParentFragmentManager().setFragmentResultListener("result", this, new FragmentResultListener(){
@Override
public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) {
if(result != null)
titleData = result.getStringArrayList("title");
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_write_routine, container, false);
initViews(rootView);
setPageTitle();
return rootView;
}
public void setPageTitle() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String new_title = String.join(" / ", titleData);
title.setText(new_title);
}
else {
StringBuilder new_title = new StringBuilder();
for (int i = 0; i < titleData.size(); i++) {
if (i == titleData.size() - 1) {
new_title.append(titleData.get(i));
break;
}
new_title.append(titleData.get(i)).append(" / ");
}
title.setText(new_title);
}
}
}