在首次启动活动期间,自定义视图动画不流畅

Che*_*eng 5 animation android

我有一个自定义视图,该视图将在

  1. 活动首次启动。
  2. 操作栏下拉菜单上的选择更改。

代码看起来像

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();
            }

        });  
Run Code Online (Sandbox Code Playgroud)

我希望animateCurrentBarHeight仅在Fragment准备好后才开始动画()。

我用addOnGlobalLayoutListener。但是,正如您在我的视频中看到的那样,似乎动画甚至发生在Fragment用户看不到之前。

https://www.youtube.com/watch?v=87_DOuZw88w&feature=youtu.be

如果我仅在的过程onNavigationItemSelected中执行动画Activity(使用相同的动画代码,即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();        
}
Run Code Online (Sandbox Code Playgroud)

阅读所有建议答案后的最终答案

@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);
        }

    });        
Run Code Online (Sandbox Code Playgroud)

Ale*_*ood 5

我不相信有办法在这样的活动过渡上设置结束监听器,因此一种可能的解决方案是简单地设置动画的开始延迟。这将确保在第二个活动仍在向屏幕动画/淡入淡出时动画不会开始。

可以通过调用以下命令获取默认的活动过渡持续时间:

getResources().getInteger(android.R.integer.config_mediumAnimTime);
Run Code Online (Sandbox Code Playgroud)