#javascript #android-studio #android-fragments #android-activity #bottom-sheet
#javascript #android-studio #android-фрагменты #android-активность #нижняя таблица
Вопрос:
Проблема может быть связана с моей архитектурой, но я не слишком уверен.
Вот в чем проблема.
У меня есть действие, которое инициирует фрагмент. .xml
Файл этого действия содержит, a FrameLayout
для фрагмента (назовем его FragmentA) и a CoordinatorLayout
, который действует как нижняя таблица.
Внутри нижней таблицы есть еще FrameLayout
один для другого фрагмента (назовем его FragmentB).
Чего я пытаюсь добиться, так это того, что когда нижний лист полностью расширяется, тогда, на его FrameLayout
основе, я инициирую FragmentB.
Чтобы сэкономить место, я решил обрабатывать все, что связано с нижней таблицей, в другом отдельном классе с именем BottomSheetManagement
Затем я прикрепляюсь BottomSheetCallback
к своему нижнему листу, и когда его состояние expanded
, я вызываю метод initiateFragment(currentFragmentID, WorkFragment.newInstance())
.
Этот метод создается в вызываемом интерфейсе FragmentHost
, который реализован в моем MainActivity. Таким образом, когда я вызываю initiateFragment(currentFragmentID, WorkFragment.newInstance())
, я фактически вызываю метод с тем же именем в моем MainActivity.
Однако, когда я тестирую свое приложение и перетаскиваю нижнюю таблицу наверх, я получаю сообщение об ошибке : IllegalStateException : Activity has been destroyed.
Я не понимаю, как с момента initiateFragment(currentFragmentID, WorkFragment.newInstance())
ввода я удостоверяюсь, что действие все еще существует (до !isfinishing() amp;amp; !isDestroyed()
конца)
Что я могу сделать?
MainActivity.java
public class MainActivity extends AppCompatActivity implements FragmentHost {
//BottomSheet Variables
View bottomSheet;
RelativeLayout bottomSheetHeader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow();
}
//Handle BottomSheet
bottomSheet = findViewById(R.id.bottom_sheet);
bottomSheetHeader = findViewById(R.id.BottomSheet_Layout_Header);
bottomSheetManagement();
}
private void bottomSheetManagement(){
BottomSheetManagement bottomSheetManagement = new BottomSheetManagement();
bottomSheetManagement.handleBottomSheet(R.id.work_container, bottomSheet, bottomSheetHeader);
}
@Override
public void initiateFragment(int containerID, Fragment fragment) {
if (!isFinishing() amp;amp; !isDestroyed()){
getSupportFragmentManager().beginTransaction()
.replace(containerID, fragment)
.commit();
}
}
}
BottomSheetManagement.java
public class BottomSheetManagement {
private BottomSheetBehavior bottomSheetBehavior;
private int activeBottomSheetState;
public void handleBottomSheet(int currentFragmentID, View bottomSheet, RelativeLayout bottomSheetHeader){
FragmentHost fragmentHost = new MainActivity();
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetHeader.setOnClickListener(v -> {
switch (bottomSheetBehavior.getState()){
case BottomSheetBehavior.STATE_COLLAPSED:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
case BottomSheetBehavior.STATE_EXPANDED:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
break;
}
});
bottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState){
case BottomSheetBehavior.STATE_EXPANDED:
fragmentHost.initiateFragment(currentFragmentID, WorkFragment.newInstance());
break;
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
}
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@ id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@ id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
app:behavior_hideable="false"
app:behavior_peekHeight="50dp"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:id="@ id/BottomSheet_Layout_Header">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/app_name"
style="?attr/titleTextAppearance"
android:textColor="?attr/colorOnSurface"/>
</RelativeLayout>
<FrameLayout
android:id="@ id/work_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>
Комментарии:
1. не могли бы вы поделиться файлом макета
2. @NagoorBhasha Конечно, я только что отредактировал вопрос. Проверьте это.
3. могу ли я узнать, какое исключение вы получаете
4.
java.lang.IllegalStateException: Activity has been destroyed at androidx.fragment.app.FragmentManagerlmpl.enqueueAction(FragmentManagerlmpl.java:1566) at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:317) at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:282) at com.example.app.MainActivity.initiateFragment(MainActivity.java:44) at com.example.app.views.BottomSheetManagement$1.onStateChanged(BottomSheetManagement.java:36) at com.google.android.material.bottomsheet.BottomSheetBehavior.setStateInternal(BottomSheetBehavior.java:996)
и т.д…5. Вам нужно все исключение?
Ответ №1:
Вы должны назначить контекст MainActivity, уже созданный для fragmentHost, вместо создания нового контекста, который вы делаете, написав ‘new MainActivivty ()’, который уничтожает предыдущую MainActivity, откуда вы вызывали BottomSheetManagement, и создает новую. Измените свой код управления нижней таблицей на,
public class BottomSheetManagement {
private BottomSheetBehavior bottomSheetBehavior;
private int activeBottomSheetState;
private FragmentHost fragmentHost;
public void handleBottomSheet(FragmentHost context, int currentFragmentID, View bottomSheet, RelativeLayout bottomSheetHeader){
fragmentHost = (FragmentHost) context;
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetHeader.setOnClickListener(v -> {
и в коде MainActivity измените метод на
private void bottomSheetManagement(){
BottomSheetManagement bottomSheetManagement = new BottomSheetManagement();
bottomSheetManagement.handleBottomSheet(this, R.id.work_container, bottomSheet, bottomSheetHeader);
}