gpt4 book ai didi

c# - 从不同类调用函数时获取空值

转载 作者:太空宇宙 更新时间:2023-11-03 12:03:24 24 4
gpt4 key购买 nike

我有一个问题...我有 2 个 FrameLayout,第一个是可以更改的 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(); 错误:

Unhandled Exception: Java.Lang.IllegalStateException: Activity has been destroyed occurred

我还可以看到该片段的值为 null,而 PreviousFragment 的值为 null。这是开头的2个switch case造成的,因为IntroAddProject、ShapeSelectionFragment和ShapeFormationFragment都是null。这很奇怪,因为我在 MainActivity 的 OnCreate 中给了它们一个值。

有人可以帮助我吗?

最佳答案

您的问题是您正在片段中新建一个 MainActivity 对象。这在 Android 中是不可能的。事件必须由操作系统初始化

相反,您可以使用已经属于 Fragment 类的 Activity 属性并将其转换为 MainActivity,这样您就可以在其中调用方法。像这样:

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

?. 是为了防止在 Activity 为 null 的情况下发生异常,因为 Fragment 已分离。

希望这有效。-

注意:删除类顶部的 mainActivity 对象,因为您不需要它。

我是这个意思。

MainActivity mainActivity = new MainActivity();

注意 2:请注意,尽管上面的代码可以工作并解决您的问题,但这并不是 Activity 和 Fragment 之间通信的最佳方式。在这里,我们耦合了 ActionBar_Setup 片段,仅供 MainActivity 事件使用,片段的优点之一是它们可以重复使用。

为避免这种耦合,一种使其工作的方法是定义一个接口(interface),其中包含您希望事件遵循的方法,然后将此实现作为片段要求的一部分。然后,您可以转换为界面,而不是转换为特定的 Activity。

我可以稍后更新这个答案,如果您需要,我可以添加一个示例。

关于c# - 从不同类调用函数时获取空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56107668/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com