我正在使用兼容性库转换应用程序以使用片段。
现在我有许多活动(A B C D)互相链接,D有一个按钮'OK',按下后调用完成,然后通过onActivityResult()
冒泡,另外销毁C和B.
对于我的前Honycomb片段版本,每个活动实际上是片段Af Bf Cf Df的包装器。所有活动均通过startActivityForResult()
启动,每个片段中的onActivityResult()
可以愉快地致电getActivity().finish()
我遇到的问题是在我的Honeycomb版本中我只有一个活动A,并且使用FragmentManager
加载片段Bf,Cf,Df。
我不明白的是,当按下“确定”以删除片段Df,Cf和Bf时,在Df中该怎么办?
我尝试让片段从堆栈中弹出,但这会导致异常。 onActivityResult()
没用,因为我没有使用startActivityForResult()
加载片段。
我是否完全以错误的方式思考这个问题?我是否应该实现某种与父片段或活动进行通信的侦听器,以便使用事务管理器进行弹出?
答案 0 :(得分:308)
虽然它可能不是最好的方法,但我能想到的最接近的等价物是支持/兼容性库
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
或
getActivity().getFragmentManager().beginTransaction().remove(this).commit();
否则。
此外,您可以使用backstack并弹出它。但请记住,片段可能不在backstack上(取决于在那里获得它的片段事务..)或者它可能不是最后一个进入堆栈,因此弹出堆栈可能会删除错误的...
答案 1 :(得分:55)
我不明白的是,当按下“确定”以删除片段Df,Cf和Bf时,在Df中该怎么做?
步骤#1:让Df告诉D“哟!我们得到了OK点击!”通过调用方法,在活动本身或活动提供的接口实例上。
步骤2:让D通过FragmentManager
删除片段。
托管活动(D)是知道活动中其他片段(与其他活动相比)的活动。因此,可能会影响片段混合的片段内事件应该传播到活动,这将使适当的编排移动。
答案 2 :(得分:35)
你应该让Activity处理添加和删除片段,正如CommonsWare所说,使用一个监听器。这是一个例子:
public class MyActivity extends FragmentActivity implements SuicidalFragmentListener {
// onCreate etc
@Override
public void onFragmentSuicide(String tag) {
// Check tag if you do this with more than one fragmen, then:
getSupportFragmentManager().popBackStack();
}
}
public interface SuicidalFragmentListener {
void onFragmentSuicide(String tag);
}
public class MyFragment extends Fragment {
// onCreateView etc
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
suicideListener = (SuicidalFragmentListener) activity;
} catch (ClassCastException e) {
throw new RuntimeException(getActivity().getClass().getSimpleName() + " must implement the suicide listener to use this fragment", e);
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Attach the close listener to whatever action on the fragment you want
addSuicideTouchListener();
}
private void addSuicideTouchListener() {
getView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
suicideListener.onFragmentSuicide(getTag());
}
});
}
}
答案 3 :(得分:17)
在Activity / AppCompatActivity中:
@Override
public void onBackPressed() {
if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
// if you want to handle DrawerLayout
mDrawerLayout.closeDrawer(GravityCompat.START);
} else {
if (getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}
}
然后调用片段:
getActivity().onBackPressed();
或者像其他答案中所说的那样,在片段中调用它:
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
答案 4 :(得分:4)
查看DialogFragment是否满足您的需求。 DialogFragment有一个dismiss()方法。我认为更清洁。
答案 5 :(得分:3)
我为此创建了简单的方法
popBackStack(getSupportFragmentManager());
将其放在我的ActivityUtils类
中public static void popBackStack(FragmentManager manager){
FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
这很棒,玩得开心!
答案 6 :(得分:1)
如果您需要从Backstack历史记录中的第四个片段弹回到第一个片段,请使用标签!!!
当您添加第一个片段时,您应该使用以下内容:
getFragmentManager.beginTransaction.addToBackStack("A").add(R.id.container, FragmentA).commit()
或
getFragmentManager.beginTransaction.addToBackStack("A").replace(R.id.container, FragmentA).commit()
当你想要显示碎片B,C和D时,你可以使用它:
getFragmentManager.beginTransaction.addToBackStack("B").replace(R.id.container, FragmentB, "B").commit()
和其他信件......
要返回Fragment
A,只需调用popBackStack(0, "A")
,是的,使用添加时指定的标志,并注意它必须与命令{{1}中的标志相同},而不是命令中使用的替换或添加。
欢迎你;)
答案 7 :(得分:1)
OnCreate中:
//Add comment fragment
container = FindViewById<FrameLayout>(Resource.Id.frmAttachPicture);
mPictureFragment = new fmtAttachPicture();
var trans = SupportFragmentManager.BeginTransaction();
trans.Add(container.Id, mPictureFragment, "fmtPicture");
trans.Show(mPictureFragment); trans.Commit();
这就是我在点击事件1中隐藏片段的方式
//Close fragment
var trans = SupportFragmentManager.BeginTransaction();
trans.Hide(mPictureFragment);
trans.AddToBackStack(null);
trans.Commit();
然后将其显示回事件2
var trans = SupportFragmentManager.BeginTransaction();
trans.Show(mPictureFragment); trans.Commit();
答案 8 :(得分:0)
如果您使用的是新的导航组件,则很简单
findNavController().popBackStack()
它将为您完成所有的FragmentTransaction。
答案 9 :(得分:0)
在同一片段内关闭片段
getActivity().onBackPressed();
答案 10 :(得分:-1)
parentFragmentManager.apply {
val f = this@MyFragment
beginTransaction().hide(f).remove(f).commit()
}
答案 11 :(得分:-7)
为什么不只是:
getActivity()。finish();