来自另一个片段的 FragmentTransaction 调用使 activity 变量为空
FragmentTransaction call from another fragment makes activity variables null
背景使用 ValueAnimator
和自定义 ValueAnimator.Update
方法制作动画。在 activity onCreate
方法中,使用 FragmentTransaction
第一个片段调用。在第一个片段中,另一个 FragmetTranstaction
基于用户按钮点击调用。在第一笔交易中一切正常,但在第二笔交易中,ValueAnimator.Update
中使用的 activity 变量变为空。问题出在哪里?
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();
}
背景变量和矩阵变量均引发空指针异常
animate()
函数:
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();
}
bgAnimator.Update
委托
中引发的异常
我使用 try 和 catch 解决了这个问题。
这是我的新动画函数:
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);
}
}
只需要在需要时填充空变量即可!
但是正如你所猜到的,这并不是一个简单的回答来解释为什么后台在这个过程中变为空!
背景使用 ValueAnimator
和自定义 ValueAnimator.Update
方法制作动画。在 activity onCreate
方法中,使用 FragmentTransaction
第一个片段调用。在第一个片段中,另一个 FragmetTranstaction
基于用户按钮点击调用。在第一笔交易中一切正常,但在第二笔交易中,ValueAnimator.Update
中使用的 activity 变量变为空。问题出在哪里?
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();
}
背景变量和矩阵变量均引发空指针异常
animate()
函数:
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();
}
bgAnimator.Update
委托
我使用 try 和 catch 解决了这个问题。
这是我的新动画函数:
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);
}
}
只需要在需要时填充空变量即可!
但是正如你所猜到的,这并不是一个简单的回答来解释为什么后台在这个过程中变为空!