The Background is animated with a ValueAnimator
and a customized ValueAnimator.Update
method. In activity onCreate
method, with FragmentTransaction
first 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
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!.