如何修复已添加到我的代码中的 Fragment?
How do I fix Fragment already added in my code?
我从 A fragment
打开一个 dialog fragment
,当对话框片段关闭时,
我想同时从 A fragment
切换到 B fragment
。
但我一直收到 Fragment already added error
。
我正在使用 show()
而不是 replace(
) 来更改屏幕。
Fragment already added error
在网上很容易解决,但是
我不锻炼奇怪。
可能是我的代码有问题,请告诉我问题出在哪里。
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, tag);
}
else {
transaction.show(fragment);
}
transaction.setPrimaryNavigationFragment(fragment);
transaction.setReorderingAllowed(true);
transaction.commitNow();
return true;
}
});
}
// Method for screen switching
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();
fragment.setArguments(curFrag.getArguments());
transaction.add(R.id.content_layout, fragment, tag);
} else {
transaction.show(fragment);
}
transaction.setReorderingAllowed(true);
transaction.commit();
}
}
WorkoutListFragment.java(片段)
public class WorkoutListFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getParentFragmentManager().setFragmentResultListener("result", this, new FragmentResultListener(){
@Override
public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) {
if(result != null)
WorkoutListFragment.this.setArguments(result);
titleData = result.getStringArrayList("title");
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_workout_list, container, false);
initViews(rootView);
((AppCompatActivity) getActivity()).setSupportActionBar((toolbar));
return rootView;
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.record_item_add, menu);
}
@Override // open dialog
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
BodyPartDialogFragment dialog = new BodyPartDialogFragment();
dialog.show(getActivity().getSupportFragmentManager(), "BodyPartDialog");
return true;
}
}
DialogFragment.java
public class BodyPartDialogFragment extends DialogFragment {
Button startBtn;
ArrayList<String> bodypart_strData;
int selectedNum;
final static String TAG = "DialogFragment";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_body_part_dialog, null);
startBtn = view.findViewById(R.id.check);
// A D D
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedNum == 0){
Toast.makeText(getContext(), "Plaese select", 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;
}
测试您的代码后,您只需要在 adding/replacing 您的片段之前重新实例化 transaction
对象。
因此,您需要在 onFragmentChanged()
中添加以下内容:
transaction = getSupportFragmentManager().beginTransaction();
这里是:
// Method for screen switching
public void onFragmentChanged() {
String tag = "WriteRoutine";
transaction = getSupportFragmentManager().beginTransaction(); // <<< THE CHANGE IS HERE
curFrag = fm.getPrimaryNavigationFragment();
if (curFrag != null) {
transaction.hide(curFrag);
}
Fragment fragment = fm.findFragmentByTag(tag);
if (fragment == null) {
fragment = new WriteRoutineFragment();
fragment.setArguments(curFrag.getArguments());
transaction.add(R.id.content_layout, fragment, tag);
} else {
transaction.show(fragment);
}
transaction.setReorderingAllowed(true);
transaction.commit();
}
我从 A fragment
打开一个 dialog fragment
,当对话框片段关闭时,
我想同时从 A fragment
切换到 B fragment
。
但我一直收到 Fragment already added error
。
我正在使用 show()
而不是 replace(
) 来更改屏幕。
Fragment already added error
在网上很容易解决,但是
我不锻炼奇怪。
可能是我的代码有问题,请告诉我问题出在哪里。
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, tag);
}
else {
transaction.show(fragment);
}
transaction.setPrimaryNavigationFragment(fragment);
transaction.setReorderingAllowed(true);
transaction.commitNow();
return true;
}
});
}
// Method for screen switching
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();
fragment.setArguments(curFrag.getArguments());
transaction.add(R.id.content_layout, fragment, tag);
} else {
transaction.show(fragment);
}
transaction.setReorderingAllowed(true);
transaction.commit();
}
}
WorkoutListFragment.java(片段)
public class WorkoutListFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getParentFragmentManager().setFragmentResultListener("result", this, new FragmentResultListener(){
@Override
public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) {
if(result != null)
WorkoutListFragment.this.setArguments(result);
titleData = result.getStringArrayList("title");
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_workout_list, container, false);
initViews(rootView);
((AppCompatActivity) getActivity()).setSupportActionBar((toolbar));
return rootView;
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.record_item_add, menu);
}
@Override // open dialog
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
BodyPartDialogFragment dialog = new BodyPartDialogFragment();
dialog.show(getActivity().getSupportFragmentManager(), "BodyPartDialog");
return true;
}
}
DialogFragment.java
public class BodyPartDialogFragment extends DialogFragment {
Button startBtn;
ArrayList<String> bodypart_strData;
int selectedNum;
final static String TAG = "DialogFragment";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_body_part_dialog, null);
startBtn = view.findViewById(R.id.check);
// A D D
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedNum == 0){
Toast.makeText(getContext(), "Plaese select", 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;
}
测试您的代码后,您只需要在 adding/replacing 您的片段之前重新实例化 transaction
对象。
因此,您需要在 onFragmentChanged()
中添加以下内容:
transaction = getSupportFragmentManager().beginTransaction();
这里是:
// Method for screen switching
public void onFragmentChanged() {
String tag = "WriteRoutine";
transaction = getSupportFragmentManager().beginTransaction(); // <<< THE CHANGE IS HERE
curFrag = fm.getPrimaryNavigationFragment();
if (curFrag != null) {
transaction.hide(curFrag);
}
Fragment fragment = fm.findFragmentByTag(tag);
if (fragment == null) {
fragment = new WriteRoutineFragment();
fragment.setArguments(curFrag.getArguments());
transaction.add(R.id.content_layout, fragment, tag);
} else {
transaction.show(fragment);
}
transaction.setReorderingAllowed(true);
transaction.commit();
}