Search code examples
androidandroid-fragmentsxamarinfragmenttransaction

FragmentTransaction call from another fragment makes activity variables null


The Background is animated with a ValueAnimator and a customized ValueAnimator.Update method. In activity onCreate method, with FragmentTransactionfirst fragment calls. And from the first fragment, another FragmetTranstaction called based on user button click. On the first transaction everything works perfect but in the second one, the activity variables that used in ValueAnimator.Update goes null. Where is the problem?

Activity onCreate:

    private const int TO_LEFT = 0;
    private const int TO_RIGHT = 1;
    private const long DURATION = 15000;

    private int bgAnimDir = TO_LEFT;
    private RectF mDisplayRect = new RectF();
    private Matrix matrix = new Matrix();
    private ValueAnimator bgAnimator;

    [BindView(Resource.Id.background)]
    ImageView background;
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);
        Cheeseknife.Bind(this);

        background.Post(() =>
        {
            animate();
        });


        fragmentTransaction = FragmentManager.BeginTransaction();
        fragmentTransaction.Add(Resource.Id.home_container, new Home(), "Home");
        fragmentTransaction.Commit();
    }

The null pointer exception raised for both background and matrix variables

animate() function:

    private void animate()
    {
        updateDisplayRect();
        if (bgAnimDir == TO_LEFT)
            animate(mDisplayRect.Left, mDisplayRect.Left - (mDisplayRect.Right - background.Width));
        else
            animate(mDisplayRect.Left, 0.0f);
    }

    private void animate(float from, float to)
    {
        bgAnimator = ValueAnimator.OfFloat(from, to);
        bgAnimator.Update +=
            (object sender, ValueAnimator.AnimatorUpdateEventArgs e) =>
            {
                float value = (float)e.Animation.AnimatedValue;
                matrix.Reset();
                matrix.PostTranslate(value, 0);
                background.ImageMatrix = matrix;
            };
        bgAnimator.SetDuration(DURATION);
        bgAnimator.AnimationEnd +=
            (object sender, EventArgs e) =>
            {
                bgAnimDir = bgAnimDir == TO_LEFT ? TO_RIGHT : TO_LEFT;
                animate();
            };
        bgAnimator.Start();
    }

Exceptions raised in bgAnimator.Update delegate


Solution

  • I solved the problem by using try , catch.

    Here is my new animate function:

        private void animate(float from, float to)
        {
            bgAnimator = ValueAnimator.OfFloat(from, to);
            bgAnimator.Update +=
                (object sender, ValueAnimator.AnimatorUpdateEventArgs e) =>
                {
                    try
                    {
                        float value = (float)e.Animation.AnimatedValue;
                        matrix.Reset();
                        matrix.PostTranslate(value, 0);
                        background.ImageMatrix = matrix;
                    }
                    catch
                    {
                        background = (ImageView)FindViewById(Resource.Id.background);
                    }
                };
            bgAnimator.SetDuration(DURATION);
            bgAnimator.AnimationEnd +=
                (object sender, EventArgs e) =>
                {
                    bgAnimDir = bgAnimDir == TO_LEFT ? TO_RIGHT : TO_LEFT;
                    animate();
                };
            bgAnimator.Start();
        }
    
        private void updateDisplayRect()
        {
            try
            {
                mDisplayRect.Set(0, 0, background.Drawable.IntrinsicWidth, background.Drawable.IntrinsicHeight);
                matrix.MapRect(mDisplayRect);
            }
            catch
            {
                background = (ImageView)FindViewById(Resource.Id.background);
            }
        }
    

    Just fill the null variable when its need to be!

    But as you can guess, this is not a briefly answer to explain why the background goes null in the process!.