findFragmentByTag() returns 现有 fragmentTag 为空
findFragmentByTag() returns null on existing fragmentTag
我有一个 Activity
和一个 FragmentContainer
,它只会显示两个 Fragment
之一。
通过单击第一个 Fragment
(CreateTasksListFragment
) 的 Button
,可以显示另一个 (CreateTaskFragment
)。
当用户单击该按钮时,CreateTasksListFragment
被隐藏并显示 CreateTaskFragment
的新实例。然后,将显示 CreateTasksListFragment
(通过单击 CreateTaskFragment
的按钮),并且必须删除 CreateTaskFragment
。
问题是,当我尝试从 FragmentManager
中获取 CreateTasksListFragment
的最后一个实例以再次显示它时,即使我通过调用 getBackStackEntryAt()
、findFragmentByTag()
正确地获得了它的标签returns 空.
我不认为有待处理的交易,所以我可能犯了另一种错误。
如果您知道实现此目标的更好方法,即使不使用这种方法,也请分享它们。
这里是问题感兴趣的代码:
CreateTasksActivity.java
@Override
protected void onStart() {
super.onStart();
Bundle bundle = new Bundle();
...
CreateTasksListFragment fragment = new CreateTasksListFragment();
fragment.setArguments(bundle);
setCurrentFragment(fragment, CreateTasksListFragment.TAG);
}
/**
* Sets new fragment
* @param fragment
*/
public void setCurrentFragment(Fragment fragment, String fragmentTag){
getSupportFragmentManager().beginTransaction()
.replace(R.id.create_tasks_fragment_container, fragment)
.addToBackStack(fragmentTag)
.commit();
}
CreateTasksListFragment.java
mNewTaskFabButton.setOnClickListener(v -> {
Task task = new Task(mTasks.size() + 1);
mTasks.add(task);
Bundle bundle = new Bundle();
bundle.putParcelable(CreateTaskFragment.TASK_EXTRA, task);
CreateTaskFragment fragment = new CreateTaskFragment();
fragment.setArguments(bundle);
// Replacing fragment with the fragment to create a single task
getParentFragmentManager()
.beginTransaction()
.hide(CreateTasksListFragment.this)
.add(R.id.create_tasks_fragment_container, fragment)
.addToBackStack(null)
.commit();
});
CreateTaskFragment.java
mCreateTaskButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
...
FragmentManager fm = getParentFragmentManager();
Fragment fragment;
String fragmentTag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2).getName(); // -2 since it starts counting from 0 and we need the second-last transaction
Log.d("log1", fragmentTag);
fragment = fm.findFragmentByTag(fragmentTag);
Log.d("log2", String.valueOf(fragment == null));
fm.beginTransaction()
.remove(CreateTaskFragment.this)
.show(fragment)
.commit();
}
});
日志
2021-05-13 21:19:44.952 20865-20865/* D/log1: CreateTasksListFragmentTag
2021-05-13 21:19:44.952 20865-20865/* D/log2: true
标签与我将第一笔交易放在后台堆栈时使用的标签相同。
您从 fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2).getName()
返回的 name
是 name
,您传递给 addToBackStack(String name)
。这是与片段关联的标签完全不同的概念。
如果要设置与片段关联的标签,则需要使用 takes a tag:
的版本将一个标签设置为 replace()
调用的一部分
getSupportFragmentManager().beginTransaction()
.replace(R.id.create_tasks_fragment_container, fragment, fragmentTag)
.addToBackStack(fragmentTag)
.commit();
注意:您应该 永远不要 将使用 addToBackStack()
的片段交易与不使用 addToBackStack()
的交易混合,因为这会破坏 [= =18=] 和系统后退按钮(假定自上次 addToBackStack()
交易以来您没有更改任何片段)。
我有一个 Activity
和一个 FragmentContainer
,它只会显示两个 Fragment
之一。
通过单击第一个 Fragment
(CreateTasksListFragment
) 的 Button
,可以显示另一个 (CreateTaskFragment
)。
当用户单击该按钮时,CreateTasksListFragment
被隐藏并显示 CreateTaskFragment
的新实例。然后,将显示 CreateTasksListFragment
(通过单击 CreateTaskFragment
的按钮),并且必须删除 CreateTaskFragment
。
问题是,当我尝试从 FragmentManager
中获取 CreateTasksListFragment
的最后一个实例以再次显示它时,即使我通过调用 getBackStackEntryAt()
、findFragmentByTag()
正确地获得了它的标签returns 空.
我不认为有待处理的交易,所以我可能犯了另一种错误。
如果您知道实现此目标的更好方法,即使不使用这种方法,也请分享它们。
这里是问题感兴趣的代码:
CreateTasksActivity.java
@Override
protected void onStart() {
super.onStart();
Bundle bundle = new Bundle();
...
CreateTasksListFragment fragment = new CreateTasksListFragment();
fragment.setArguments(bundle);
setCurrentFragment(fragment, CreateTasksListFragment.TAG);
}
/**
* Sets new fragment
* @param fragment
*/
public void setCurrentFragment(Fragment fragment, String fragmentTag){
getSupportFragmentManager().beginTransaction()
.replace(R.id.create_tasks_fragment_container, fragment)
.addToBackStack(fragmentTag)
.commit();
}
CreateTasksListFragment.java
mNewTaskFabButton.setOnClickListener(v -> {
Task task = new Task(mTasks.size() + 1);
mTasks.add(task);
Bundle bundle = new Bundle();
bundle.putParcelable(CreateTaskFragment.TASK_EXTRA, task);
CreateTaskFragment fragment = new CreateTaskFragment();
fragment.setArguments(bundle);
// Replacing fragment with the fragment to create a single task
getParentFragmentManager()
.beginTransaction()
.hide(CreateTasksListFragment.this)
.add(R.id.create_tasks_fragment_container, fragment)
.addToBackStack(null)
.commit();
});
CreateTaskFragment.java
mCreateTaskButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
...
FragmentManager fm = getParentFragmentManager();
Fragment fragment;
String fragmentTag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2).getName(); // -2 since it starts counting from 0 and we need the second-last transaction
Log.d("log1", fragmentTag);
fragment = fm.findFragmentByTag(fragmentTag);
Log.d("log2", String.valueOf(fragment == null));
fm.beginTransaction()
.remove(CreateTaskFragment.this)
.show(fragment)
.commit();
}
});
日志
2021-05-13 21:19:44.952 20865-20865/* D/log1: CreateTasksListFragmentTag
2021-05-13 21:19:44.952 20865-20865/* D/log2: true
标签与我将第一笔交易放在后台堆栈时使用的标签相同。
您从 fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 2).getName()
返回的 name
是 name
,您传递给 addToBackStack(String name)
。这是与片段关联的标签完全不同的概念。
如果要设置与片段关联的标签,则需要使用 takes a tag:
的版本将一个标签设置为replace()
调用的一部分
getSupportFragmentManager().beginTransaction()
.replace(R.id.create_tasks_fragment_container, fragment, fragmentTag)
.addToBackStack(fragmentTag)
.commit();
注意:您应该 永远不要 将使用 addToBackStack()
的片段交易与不使用 addToBackStack()
的交易混合,因为这会破坏 [= =18=] 和系统后退按钮(假定自上次 addToBackStack()
交易以来您没有更改任何片段)。