好的,我面临一个奇怪的问题,我似乎无法解决,所以我想问一下。
简而言之,我面临的问题是:
关闭后,我创建的全屏对话框将消耗(一次)后按按钮。结果什么也没发生,用户需要再次按下“后退”按钮以关闭“活动”。
全文: 我有一个活动和两个片段。下面是一些代码...:
public class AppActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_app);
if (savedInstanceState == null) {
showMainFragment();
}
}
(...)
private void showMainFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
EditAppActivityFragment fr = new MainAppActivityFragment();
fragmentTransaction.add(R.id.fragment_container_main_app, fr, "main");
fragmentTransaction.commit();
}
private void showDialogFullscreen() {
AppConfigDialogFragment newFragment = new AppConfigDialogFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.add(R.id.fragment_container_main_app, newFragment, "dialog")
.addToBackStack("dialog").commit();
}
}
activity_main_app.xml
:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/fragment_container_main_app"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
这里是MainAppActivityFragment
:
public class MainAppActivityFragment extends Fragment implements {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main_app, container, false);
initToolbar();
updateActionBar();
setViewModel();
return binding.getRoot();
}
}
还有fragment_main_app.xml
:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_main_app"
tools:context=".ui.activity.fragment.EditAppActivityFragment">
<data>
<variable
name="viewModel"
type="..." />
</data>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
(...)
</android.support.design.widget.CoordinatorLayout>
</layout>
这里是AppDialogFragment
:
public class AppDialogFragment extends DialogFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.dialog_configure_app, container, false);
getBundleData();
setAppBarButtonListeners();
setViewModel();
return binding.getRoot();
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
private void setAppBarButtonListeners() {
binding.imageButtonConfigClose
.setOnClickListener(v -> dismiss());
binding.imageButtonConfigSave
.setOnClickListener(v -> {
(...)
dismiss();
});
}
}
那么会发生什么:
AppActivity
启动,然后创建MainAppActivityFragment
。 showDialogFullscreen()
,从而创建AppDialogFragment
。DialogFragment
,用户可以保存或取消她/他所做的更改。 (请注意,我要使用全屏对话框)MainAppActivityFragment
再次出现。到目前为止一切顺利。会发生什么?
我在registerFragmentLifecycleCallbacks
上使用FragmentManager
来查看正在发生的事情(more details here)。
DialogFragment
时,最后一个呼叫是onFragmentViewDestroyed
。到目前为止一切顺利。onFragmentDestroyed
被调用,然后onFragmentDetached
DialogFragment
被销毁,再次按返回按钮,将关闭活动(按预期)。因此,我认为我们可以通过以下技巧或肮脏的骇客(inspired by this post)来强制破坏Fragment:
fragmentManager.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {
(...)
@Override
public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) {
super.onFragmentViewDestroyed(fm, f);
if (f.getTag().equals("dialog") {
// Yes, this is being called...
FragmentTransaction tr = fm.beginTransaction();
tr.remove(f).commit();
}
}
(...)
}
但是什么也没发生!我没有看到对onFragmentDestroyed
和onFragmentDetached
的任何呼叫。当然,问题仍然存在。
然后我看到了这篇文章:"What is difference between FragmentTransaction.add().commit() and DialogFragment.show()?"。声称它们是相同的。好吧,就我而言,它们不是:
DialogFragment
不再是全屏显示,而是一个很小的覆盖。然后我认为可以...让我们找出一种使全屏显示的方法。 I read this post。没事。我能得到的最接近的是几乎是全屏对话框(我仍然可以看到前一个片段的很小一部分)。
我的问题:
tr.remove(f).commit()
不破坏片段as claimed here?.show()
和blah blah.commit()
为什么表现不同?我迷路了!任何帮助表示赞赏!谢谢! (顺便说一句,我只保留了看似相关的信息。如果我缺少什么,请告诉我)