无法为从getWindowManager()。addView创建的视图设置动画

时间:2014-05-04 11:05:43

标签: android android-layout android-animation

我正在做这个吧

showing-refreshing-message-in-action-bar

它的工作正常。但是,我想让它从顶部向下滑动。

我可以为布局中创建的其他对象设置动画,但不能通过getWindowManager()创建.addview

这适用于当前布局中的对象

switch(item.getItemId())
{
    case R.id.zoomInOut:
        TextView image = (TextView)findViewById(R.id.textView);
        Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.myanimation);
        image.startAnimation(animation);
        return true;
    case R.id.rotate360:
        TextView image1 = (TextView)findViewById(R.id.textView);
        Animation animation1 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.clockwise);
        image1.startAnimation(animation1);
        return true;
    case R.id.fadeInOut:
        TextView image2 = (TextView)findViewById(R.id.textView);
        Animation animation2 = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
        image2.startAnimation(animation2);
        return true;
}

这不适用于我的视图,即由getWindowManager()。addview

添加
    /** The notification layout */
    private TextView mMessage;

    public void showLoadingMessage(Context context,String msg) {

        // Initialize the layout
        if (mMessage == null) {
            final LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mMessage = (TextView) inflater.inflate(R.layout.test, null);
            mMessage.setBackgroundColor(getResources().getColor(R.color.holo_green_light));
            mMessage.setText(msg);
        }

        // Add the View to the
        getWindowManager().addView(mMessage,getActionBarLayoutParams());

        //ANIMATION FOR THIS LAYOUT START HERE
        Animation aa = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.fade);
        mMessage.startAnimation(aa);

    }

    public void removeLoadingMessage() {
        if (mMessage != null && mMessage.getWindowToken() != null) {
            getWindowManager().removeViewImmediate(mMessage);
            mMessage = null;
        }
    }


    private WindowManager.LayoutParams getActionBarLayoutParams() {
        // Retrieve the height of the status bar
        final Rect rect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        final int statusBarHeight = rect.top;


        // Create the LayoutParams for the View
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,200,
                WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
//        params.gravity = Gravity.TOP;
        params.x = 0;
        params.y = statusBarHeight;

        return params;
    }

1 个答案:

答案 0 :(得分:1)

  

我想动画它从顶部向下滑动。

致电WindowManager.addView后,您可以将ViewTreeObserver.OnGlobalLayoutListener附加到View并使用它来获取身高,然后使用ObjectAnimator执行翻译。这是一个例子:

mMessage.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
        // Get the height of the view
        final int h = mMessage.getHeight();
        // Remove the OnGlobalLayoutListener callback
        mMessage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        // Slide down from the top
        final ObjectAnimator oa = ObjectAnimator.ofFloat(mMessage, "translationY", -h, 0f);
        oa.setDuration(250);
        oa.start();
    }

});

如果您想稍后将其重新播放,请执行相反的翻译并附加AnimatorListener以了解何时致电WindowManager.removeViewImmediate。例如:

private void removeLoadingMessage(boolean animate) {
    if (mMessage != null && mMessage.getWindowToken() != null) {
        // Detach the View immediately, don't wait for the animation to end
        if (!animate) {
            getWindowManager().removeViewImmediate(mMessage);
            mMessage = null;
            return;
        }

        // Slide back up
        final int h = mMessage.getHeight();
        final ObjectAnimator oa = ObjectAnimator.ofFloat(mMessage, "translationY", 0f, -h);
        oa.setDuration(250);
        // Wait until the end of the animation to detach the View
        oa.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                getWindowManager().removeViewImmediate(mMessage);
                mMessage = null;
            }
        });
        oa.start();
    }
}

为了避免任何泄密,在Activity.onDestroy中您需要使用removeLoadingMessage(false);来确保ViewWindow正确分离。