Сбой приложения при попытке инициировать фрагмент на нижнем листе

#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);
    }