如何让一个片段删除自己,即它的等效完成()?

我正在转换一个应用程序使用片段使用兼容性库。 现在,我有许多活动(a BC D),它们相互链接,D有一个按钮“OK”,当按下调用完成,然后气泡通过onActivityResult()额外破坏C和B。

对于我的前蜂窝片段版本,每个活动都是有效的包装碎片Af Bf Cf Df。所有活动都是通过startActivityForResult()onActivityResult()启动的,每个片段都可以愉快地调用getActivity().finish()

我遇到的问题是,在我的蜂窝版本中,我只有一个活动,A,片段Bf, Cf, Df是使用FragmentManager加载的。

我不明白的是,在Df中,当'OK'被按下以删除Df, Cf和Bf片段时,要做什么?

我试着让片段弹出自己的堆栈,但这导致了一个异常。onActivityResult()是无用的,因为我没有使用startActivityForResult()加载片段。

我是不是完全想错了?我是否应该实现某种侦听器,与父片段或活动通信,以便使用事务管理器进行弹出?

269520 次浏览

我不明白的是,在Df中,当'OK'被按下以删除Df, Cf和Bf片段时,要做什么?

第一步:让Df告诉D“哟!我们得到了OK click!”通过调用一个方法,无论是在活动本身上,还是在活动提供的接口实例上。

步骤#2:让D通过FragmentManager删除片段。

托管活动(D)知道该活动中还有哪些片段(而不是在其他活动中)。因此,可能影响片段混合的片段内事件应该传播到活动,活动将进行适当的编排移动。

虽然这可能不是最好的方法,但我能想到的最接近的等效方法是支持/兼容性库

getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();

getActivity().getFragmentManager().beginTransaction().remove(this).commit();

否则。

此外,你可以使用后台和弹出它。但是请记住,这个片段可能不在后堆栈上(取决于把它放在那里的fragmenttransaction ..),或者它可能不是最后一个进入堆栈的,所以弹出堆栈可能会删除错误的一个…

你可以使用下面的方法,它工作得很好:

getActivity().getSupportFragmentManager().popBackStack();

您应该让活动处理添加和删除片段,正如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());
}
});
}
}

如果你需要从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()

和其他信件....

要返回__abc0a,只需调用popBackStack(0, "A"),是的,使用您在添加它时指定的标志,并注意它必须是命令addToBackStack()中相同的标志,而不是命令replace或add中使用的标志。

不客气。

看看你的需求是否被一个DialogFragment所满足。DialogFragment有一个dismiss()方法。在我看来干净多了。

在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();

我创建了一个简单的方法

popBackStack(getSupportFragmentManager());

而不是把它放在ActivityUtils类中

public static void popBackStack(FragmentManager manager){
FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

工作很好,玩得开心!

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();

为什么不直接:

.finish getActivity () ();

如果您正在使用新的导航组件,简单如

findNavController().popBackStack()

它会在后面为你做FragmentTransaction。

在同一个片段中关闭一个片段

getActivity().onBackPressed();

芬兰湾的科特林- - - - - -

requireActivity().onBackPressed()
parentFragmentManager.apply {
val f = this@MyFragment
beginTransaction().hide(f).remove(f).commit()
}