I have a custom view, which will perform animation during
The code looks like
public class DividendBarChartFragment extends SherlockFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dividend_bar_chart_fragment, container, false);
// barChartCompositeViewByYear is custom view.
this.barChartCompositeViewByYear = (BarChartCompositeView)v.findViewById(R.id.bar_chart_composite_view_by_year);
final ViewTreeObserver viewTreeObserver0 = this.barChartCompositeViewByYear.getViewTreeObserver();
// Only perform animation when view is ready?!
viewTreeObserver0.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
DividendBarChartFragment.this.barChartCompositeViewByYear.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
DividendBarChartFragment.this.barChartCompositeViewByYear.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
DividendBarChartFragment.this.barChartCompositeViewByYear.animateCurrentBarHeight();
}
});
I wish to start animation (animateCurrentBarHeight
), only when the Fragment
is ready.
I use addOnGlobalLayoutListener
. However, as you can see in my video, seems like animation has happened even before Fragment
is visible to user.
https://www.youtube.com/watch?v=87_DOuZw88w&feature=youtu.be
If I only perform animation during onNavigationItemSelected
of Activity
(Using the same animation code, which is animateCurrentBarHeight
), thing went much more smoother.
https://www.youtube.com/watch?v=yvJqtOSKKok&feature=youtu.be
May I know, what is the best time I can trigger my animation code, when activity first launched, so that the animation appears natural and smooth to users?
public void animateCurrentBarHeight() {
PropertyValuesHolder barHeightScalePropertyValuesHolder = PropertyValuesHolder.ofFloat("barHeightScale", barHeightScale, 1.0f);
ValueAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(this, barHeightScalePropertyValuesHolder);
valueAnimator.setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
valueAnimator.setRepeatCount(0);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.start();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.dividend_bar_chart_fragment, container, false);
// barChartCompositeViewByYear is custom view.
this.barChartCompositeViewByYear = (BarChartCompositeView)v.findViewById(R.id.bar_chart_composite_view_by_year);
final ViewTreeObserver viewTreeObserver0 = this.barChartCompositeViewByYear.getViewTreeObserver();
viewTreeObserver0.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
DividendBarChartFragment.this.barChartCompositeViewByYear.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
DividendBarChartFragment.this.barChartCompositeViewByYear.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
final int activityTransitionDuration = getResources().getInteger(android.R.integer.config_mediumAnimTime);
final BarChartCompositeView barChartCompositeView = DividendBarChartFragment.this.barChartCompositeViewByYear;
// Key to the solution!
barChartCompositeView.postDelayed(new Runnable() {
@Override
public void run() {
barChartCompositeView.animateCurrentBarHeight();
}
}, activityTransitionDuration);
}
});
I don't believe there is a way to set an end listener on activity transitions like this, so one possible solution would be to simply set a start delay on the animation. This will ensure that the animation does not begin while the second activity is still animating/fading in to the screen.
The default activity transition duration can be obtained by calling:
getResources().getInteger(android.R.integer.config_mediumAnimTime);
Generally animations can be controlled with messages on the UI thread. Without knowing the exact implementation of that view, I would give a try in posting a runnable to be ran when all current messagese are already delivered,
Instead of ...animateCurrentBarHeight();
, Do:
new Handler().post(new Runnable(){
@Override
public void run() {
DividendBarChartFragment.this.barChartCompositeViewByYear.animateCurrentBarHeight();
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With