【问题标题】:FragmentTransaction.Replace causing white (blank?) screen in appFragmentTransaction.Replace 在应用程序中导致白色(空白?)屏幕
【发布时间】:2019-01-31 19:59:14
【问题描述】:

我的应用流程如下:

主要活动: HomeFragment -> BlackoutSetupFragment -> BlackoutFragment -> HomeFragment

由于某种原因,当我尝试从 BlackoutFragment 转到 HomeFragment 时,MainActivity 变为空,并且在我离开应用程序并返回之前什么都不会呈现。左边是 HomeFragment 通常的样子,右边是我导航回它时的样子:

我用来设置片段的方法集:

    // Which is invoked like 
    // SetFragment(typeof(HomeFragment), "Home", true, true, false);
    public void SetFragment(Type fragmentType, string fragmentName, bool addToBackStack, bool showNavigationIndicator, bool useSlideAnimation)
    {
        if (fragmentType == typeof(HomeFragment))
            SetFragment(new HomeFragment(), fragmentType, fragmentName, addToBackStack, showNavigationIndicator, useSlideAnimation);
        else if (fragmentType == typeof(BlackoutFragment))
            SetFragment(new BlackoutFragment(), fragmentType, fragmentName, addToBackStack, showNavigationIndicator, useSlideAnimation);
        else if (fragmentType == typeof(BlackoutSetupFragment))
            SetFragment(new BlackoutSetupFragment(), fragmentType, fragmentName, addToBackStack, showNavigationIndicator, useSlideAnimation);
    }

    private void SetFragment(Fragment fragment, Type fragmentType, string fragmentName, bool addToBackStack, bool showNavigationIndicator, bool useSlideAnimation)
    {
        FragmentTransaction transaction = this.FragmentManager.BeginTransaction();

        if (useSlideAnimation)
            transaction.SetCustomAnimations(Resource.Animator.enter_from_left, Resource.Animator.exit_to_right, Resource.Animator.enter_from_right, Resource.Animator.exit_to_left);

        transaction.Replace(Resource.Id.content_main_fragment_layout, fragment, fragmentType.Name);

        if (addToBackStack)
            transaction.AddToBackStack(null);

        transaction.Commit();

        this.FragmentManager.ExecutePendingTransactions();

        if (!string.IsNullOrWhiteSpace(fragmentName))
            SetAppBarTitle(fragmentName);

        if (showNavigationIndicator) _navDrawerToggle.DrawerIndicatorEnabled = true;
        else _navDrawerToggle.DrawerIndicatorEnabled = false;
    }

主要活动内容的 axml 是这样的:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_main">
    <FrameLayout
        android:id="@+id/content_main_fragment_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

有人知道这里会发生什么吗?我尝试在此处包含我认为对调试有用的所有内容,但如果需要其他内容,请给我留言。

【问题讨论】:

    标签: c# android android-fragments xamarin


    【解决方案1】:

    您不应该将初始 Fragment 添加到 backstack,因为这会导致它成为可逆事务。这意味着如果您的初始状态是“无片段”,并且您将“无片段”->“HomeFragment”的事务添加到后台堆栈,那么您可以弹回“无片段”状态。

    只需更改对初始 Fragment 的调用,使其不会将其添加到 backstack。

    【讨论】:

    • 我试过这个但没有任何运气。为了确保我没有做傻事,我什至注释掉了将片段添加到后台堆栈的代码部分,当我将片段设置为 HomeFragment 时,它仍然执行完全相同的操作。
    【解决方案2】:

    问题是使用 System.Timers.Timer 来更新 UI,并在 BlackoutFragment 上倒计时。用System.Threading.Timer 替换它似乎已经解决了这个问题。我的猜测是,在 UI 线程上运行的已用事件“RefreshView”在尝试远离片段时引起了一些奇怪。

    所以替换:

        public override void OnResume()
        {
            base.OnResume();
            //...
            _refreshTimer = new System.Timers.Timer();
            _refreshTimer.Interval = 1000;
            _refreshTimer.Elapsed += RefreshView;
            _refreshTimer.Start();
        }
    
        public override void OnPause() 
        {
            base.OnPause();
            //...
            _refreshTimer.Dispose();
        }
    

    与:

        public override void OnResume()
        {
            base.OnResume();
            //...
            _refreshTimer = new System.Threading.Timer(RefreshView, null, 0, 1000);
        }
    
        public override void OnPause()
        {
            base.OnPause();
            //...
            _refreshTimer.Dispose();
        }
    

    解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-20
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多