ОК. Я столкнулся со странной проблемой, которую, похоже, не могу решить, поэтому я решил спросить.
В двух словах проблема, с которой я сталкиваюсь, заключается в следующем:
Полноэкранный диалог, который я создаю после закрытия, будет использовать (один раз) кнопку «назад»,В результате ничего не происходит, и пользователю нужно снова нажать кнопку «Назад», чтобы закрыть «Активность».
Полная история: У меня есть Активность и два фрагмента.Ниже сначала код ...:
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
.Пока все хорошо. - Теперь вот проблема: если я нажимаю кнопку возврата, ничего не происходит (на самом деле что-то происходит, см. Ниже).Мне нужно нажать еще раз, чтобы выйти из текущей активности.И это моя проблема.Фактически, если я создаю диалоговое окно x раз, мне нужно нажать x раз кнопку «Назад», прежде чем я смогу выйти из действия.
Что происходит?
Я использовал registerFragmentLifecycleCallbacks
на FragmentManager
, чтобы увидеть, что происходит ( подробнее здесь ).
- Когда пользователь закрывает
DialogFragment
, последний вызов - onFragmentViewDestroyed
.Пока все хорошо. - Когда я нажимаю кнопку "назад" (визуально ничего не происходит), фактически фрагмент уничтожается: вызывается
onFragmentDestroyed
и затем onFragmentDetached
- Как только
DialogFragment
будет уничтожено, снова нажмите кнопку «Назад», чтобы закрыть действие (как и предполагалось).
Так что я подумал, давайте сделаем следующий трюк или грязный хак( вдохновленный этим постом ) для принудительного уничтожения фрагмента:
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
.Естественно, проблема все еще существует.
Затем я увидел этот пост: "В чем разница между FragmentTransaction.add (). Commit () и DialogFragment.show ()?" .Утверждают, что они одинаковы.Ну, в моем случае это не так:
-
DialogFragment
больше не является полноэкранным режимом, а имеет небольшой оверлей. - Кнопка возврата теперь волшебным образом "работает"!
Тогда я подумал, хорошо ... давайте найдем способ сделать этот полноэкранный режим. Я прочитал этот пост .Ничего не получалось.Самым близким, что я мог получить, был почти полноэкранный диалог (я все еще мог видеть очень небольшую часть предыдущего фрагмента).
Итак, на мои вопросы:
- Почему это происходит с кнопкой возврата в моем случае?
- Есть ли способ, которым я могу преодолеть это, используя его сейчас?
- Почему
tr.remove(f).commit()
не уничтожает фрагмент , как утверждается здесь ? - Почему
.show()
и blah blah.commit()
действуют по-разному в моем случае?
Я потерян!Любая помощь приветствуется!Спасибо!(Кстати, я сохранил только ту информацию, которая показалась мне актуальной. Если я что-то упустил, пожалуйста, дайте мне знать)