我是一名有用的助手,可以为您翻译文本。
我有一个自定义视图,在以下情况下执行动画:
- Activity首次启动。
- Action Bar下拉导航中选择更改。
代码如下:
DividendBarChartFragment.java
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();
}
});
我希望只有在Fragment
准备好后才开始动画(animateCurrentBarHeight
)。
我使用了addOnGlobalLayoutListener
。然而,如您在视频中所见,似乎动画甚至发生在Fragment
对用户可见之前。
https://www.youtube.com/watch?v=87_DOuZw88w&feature=youtu.be
如果我仅在Activity
的onNavigationItemSelected
中执行动画(使用相同的动画代码,即animateCurrentBarHeight
),则效果会更加流畅自然。
https://www.youtube.com/watch?v=yvJqtOSKKok&feature=youtu.be
请问,当活动首次启动时,最好的时间触发动画代码,以使动画出现自然而流畅?
animateCurrentBarHeight
的代码
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);
}
});
onPreDraw()
监听器而不是onGlobalLayout
监听器时会发生什么? - Alex LockwoodonPreDraw
似乎并没有什么不同。动画仍然不够流畅。 - Cheok Yan ChengonPreDraw()
比onGlobalLayout
监听器更受欢迎,因为它在绘制第一帧显示框之前立即调用。 :) - Alex Lockwood