Получение нулевого значения при вызове функции из другого класса - PullRequest
2 голосов
/ 13 мая 2019

У меня проблема ... У меня есть 2 FrameLayouts, первая - это ActionBar, который может измениться, а вторая - это расположение экрана, которое может измениться.Теперь я создал свою MainActivity следующим образом:

public class MainActivity : FragmentActivity
{
    Dictionary<string, TriangleRegistryObject> TriangleRegistry = new Dictionary<string, TriangleRegistryObject>();

    //ALL FRAGMENTS
    public Android.Support.V4.App.Fragment fragment;
    public Android.Support.V4.App.Fragment PreviousFragment;
    public Android.Support.V4.App.Fragment CurrentFragment;
    public int CurrentFragmentNum;
    public int PreviousFragmentNum;

    //ACTIONBARS
    public ActionBar_Setup actionBar_Setup;
    public ActionBar_Default actionBar_Default;
    //LAYOUTS
    public Intro_Add_Project IntroAddProject;
    public Shape_Selection ShapeSelectionFragment;
    public Shape_Formation ShapeFormationFragment;

    private string Direction;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        actionBar_Setup = new ActionBar_Setup();
        actionBar_Default = new ActionBar_Default();
        IntroAddProject = new Intro_Add_Project();
        ShapeSelectionFragment = new Shape_Selection();
        ShapeFormationFragment = new Shape_Formation();

        var TransActionBar = SupportFragmentManager.BeginTransaction();
        TransActionBar.Add(Resource.Id.ActionBarContainer, actionBar_Setup, "ActionBar_Setup");
        TransActionBar.Add(Resource.Id.ActionBarContainer, actionBar_Default, "ActionBar_Default");
        TransActionBar.Hide(actionBar_Default);
        TransActionBar.Commit();

        var TransLayout = SupportFragmentManager.BeginTransaction();
        TransLayout.Add(Resource.Id.LayoutContainer, IntroAddProject, "Intro_Add_Project");
        TransLayout.Add(Resource.Id.LayoutContainer, ShapeFormationFragment, "Shape_Formation");
        TransLayout.Hide(ShapeFormationFragment);
        TransLayout.Add(Resource.Id.LayoutContainer, ShapeSelectionFragment, "Shape_Selection");
        TransLayout.Hide(ShapeSelectionFragment);
        TransLayout.Commit();

        CurrentFragmentNum = 1;
        Direction = "Startup";
        ShowFragment(CurrentFragmentNum, 1, Direction);
    }

    public void ShowFragment (int CurrentFragmentNum, int PreviousFragmentNum, string Direction)
    {
        switch (CurrentFragmentNum)
        {
            case 1:
                fragment = IntroAddProject;
                break;
            case 2:
                fragment = ShapeSelectionFragment;
                break;
            case 3:
                fragment = ShapeFormationFragment;
                break;
        }

        switch (PreviousFragmentNum)
        {
            case 1:
                PreviousFragment = IntroAddProject;
                break;
            case 2:
                PreviousFragment = ShapeSelectionFragment;
                break;
            case 3:
                PreviousFragment = ShapeFormationFragment;
                break;
        }


        var TransLayout = SupportFragmentManager.BeginTransaction();

        switch (Direction)
        {
            case "Forwards":
                TransLayout.SetCustomAnimations(Resource.Animation.slide_in_right, Resource.Animation.slide_out_left);
                break;
            case "Backwards":
                TransLayout.SetCustomAnimations(Resource.Animation.slide_in_left, Resource.Animation.slide_out_right);
                break;
        }

        TransLayout.Hide(PreviousFragment);
        TransLayout.Show(fragment);
        TransLayout.Commit();

        CurrentFragment = fragment;

        if(CurrentFragmentNum != 4)
        {
            var TransActionBar = SupportFragmentManager.BeginTransaction();
            TransActionBar.Hide(actionBar_Default);
            TransActionBar.Show(actionBar_Setup);
            TransActionBar.Commit();
        }
        else
        {
            var TransActionBar = SupportFragmentManager.BeginTransaction();
            TransActionBar.Hide(actionBar_Setup);
            TransActionBar.Show(actionBar_Default);
            TransActionBar.Commit();
        }
    }
}

И также создал ActionBar_Setup.cs.Вот код этого фрагмента:

public class ActionBar_Setup : Android.Support.V4.App.Fragment
{
    MainActivity mainActivity = new MainActivity();

    public int CurrentFragmentNum;
    public int PreviousFragmentNum;

    public string Direction;

    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.Inflate(Resource.Layout.setup_nav_bar, container, false);

        CurrentFragmentNum = 1;
        PreviousFragmentNum = 1;

        Button btnBack = view.FindViewById<Button>(Resource.Id.btnBack);
        Button btnNext = view.FindViewById<Button>(Resource.Id.btnNext);

        btnBack.Click += btnBack_Click;
        btnNext.Click += btnNext_Click;

        return view;
    }

    public void btnBack_Click(object sender, EventArgs e)
    {
        if (CurrentFragmentNum > 1)
        {
            PreviousFragmentNum = CurrentFragmentNum;
            CurrentFragmentNum -= 1;
            Direction = "Backwards";
            mainActivity.ShowFragment(CurrentFragmentNum, PreviousFragmentNum, Direction);
        }
    }

    public void btnNext_Click(object sender, EventArgs e)
    {
        if (CurrentFragmentNum < 3)
        {
            PreviousFragmentNum = CurrentFragmentNum;
            CurrentFragmentNum += 1;
            Direction = "Forwards";
            mainActivity.ShowFragment(CurrentFragmentNum, PreviousFragmentNum, Direction);
        }
    }
}

Теперь, когда я нажимаю кнопку Next, она вызывает ShowFragment () из моей MainActivity.Это работает нормально, и все параметры заданы правильно ... Но в конце функции она вылетает на строке: TransLayout.Commit(); с ошибкой:

Необработанное исключение: Java.Lang.IllegalStateException: активность была уничтожена, произошла

Также я вижу, что фрагмент имеет значение null, а PreviousFragment имеет значение null.Это вызвано двумя случаями переключения в начале, потому что IntroAddProject, ShapeSelectionFragment и ShapeFormationFragment все null.Это странно, потому что я дал им значение в OnCreate MainActivity.

Может кто-нибудь мне помочь?

1 Ответ

1 голос
/ 13 мая 2019

Ваша проблема в том, что вы создаете объект MainActivity внутри своего фрагмента. Это невозможно в Android. Действия должны быть инициализированы ОС

Вместо этого вы можете использовать свойство Activity , которое уже является частью класса Fragment, и привести его к MainActivity , чтобы там можно было вызывать методы. Примерно так:

(Activity as MainActivity)?.ShowFragment(CurrentFragmentNum, PreviousFragmentNum, Direction);

?. предназначен для предотвращения исключения в случае, если действие равно нулю из-за отсоединения фрагмента.

Надеюсь, что это работает .-

Примечание : удалите объект mainActivity в верхней части класса, так как он вам не понадобится.

Я имел в виду это.

MainActivity mainActivity = new MainActivity();

Примечание 2 : имейте в виду, что даже если приведенный выше код сработает и решит вашу проблему, это не лучший способ связи между действиями и фрагментами. Здесь мы соединяем фрагмент ActionBar_Setup , который будет использоваться только из действия MainActivity , и одна из прелестей фрагментов в том, что они могут быть использованы повторно.

Чтобы избежать этой взаимосвязи, один из способов заставить ее работать - это определить интерфейс с методами, которым вы хотите, чтобы ваша деятельность соответствовала, а затем сделать эту реализацию как часть требования Фрагмента. Затем вместо приведения к конкретному действию вы можете привести к интерфейсу.

Я мог бы обновить этот ответ позже и добавить образец, если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...