java - 如何修复代码中已添加的片段?
问题描述
我打开一个dialog fragment
from A fragment
,当对话框片段关闭时,我想同时切换A fragment
from 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;
}
解决方案
在测试您的代码后,您只需要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();
}
推荐阅读
- python - 加权页面排名图表示
- c# - SignedCms.decode() 在 c# 中做了什么
- sql - 过程的实际语法
- d3.js - 具有可变 X 和 Y 的 D3 条形图(条形的可变宽度和高度)
- javascript - 有没有办法确定 execCommand('bold') 现在是否正在执行?
- mysql - 如何最小化 SQL 查询以非常快速地给出输出?
- node.js - 如何在 Keystone.js 中对列表进行排序?
- mysql - 将图像保存到 mysql 数据库时出现问题。程序运行完美,没有错误
- python - 如何将 Python 中的正则表达式匹配到某个字符,如果不匹配则返回 None?
- parsing - 在 go 中解析 set-cookie 标头