从其他类调用函数时获取空值

时间:2019-05-13 07:36:42

标签: c# android-fragments xamarin.android

我有一个问题...我有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);
        }
    }
}

现在,当我单击下一步按钮时,它将从我的MainActivity中调用ShowFragment()。这样就可以正常工作,并且所有参数的给出方式都正确……但是,在函数结束时,它在以下行崩溃:TransLayout.Commit();,错误:

  

未处理的异常:Java.Lang.IllegalStateException:活动具有   被摧毁了

我还可以看到该片段的值为null,而PreviousFragment的值为null。这是由于开始时有2种切换情况引起的,因为IntroAddProject,ShapeSelectionFragment和ShapeFormationFragment均为null。这很奇怪,因为我在MainActivity的OnCreate中给了它们一个值。

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

您的问题是您要在Fragment中新建一个MainActivity对象。这在Android中是不可能的。活动必须由操作系统初始化

相反,您可以使用Fragment类中已经包含的 Activity 属性,并将其强制转换为 MainActivity ,以便在那里调用方法。像这样:

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

?。是为了防止由于片段已被分离而Activity为null时发生异常。

希望这行得通。-

注意:因为不需要它,所以在类顶部删除了mainActivity对象。

我是这个意思。

MainActivity mainActivity = new MainActivity();

注释2 :请注意,即使以上代码可以正常工作并解决您的问题,这也不是在Activity和Fragments之间进行交流的最佳方式。在这里,我们耦合了仅在 MainActivity 活动中使用的 ActionBar_Setup 片段,并且片段的优点之一是它们可以被重用。

为避免这种耦合,使之起作用的一种方法是通过使用您希望活动遵守的方法定义一个接口,然后将该实现作为Fragment需求的一部分。然后,您可以强制转换为界面,而不是强制转换为特定的Activity。

我可以稍后更新此答案,并根据需要添加示例。