11

I have a view (customView) added to the WindowManager.

WindowManager mWm = (WindowManager)activity.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams(WindowManager.LayoutParams.FILL_PARENT, 0, PixelFormat.TRANSPARENT);
mWl.dimAmount = 0.0f;
mWm.addView(customView, mWl);

Inside the custom view, I will call a translate animation when close button is pressed.

//// This is the handler for the animation ////

final Handler translateHandler = new Handler();

final Runnable mtranslateUp = new Runnable() {
    public void run() {
        Log.v("TEST","mtranslateUp Runnable");
        startAnimation(translateUp);
    }
};

//// This is the listener for the close button////

View.OnClickListener closeButtonListener = new View.OnClickListener() {         

    public void onClick(View v) {
        translateHandler.post(mtranslateUp);
    }
};

//// This is the translate up animation ////

translateUp = new TranslateAnimation(0,0,0,-200);
translateUp.setFillAfter(true);
translateUp.setDuration(1000);
translateUp.setAnimationListener(new AnimationListener(){
        @Override
        public void onAnimationEnd(Animation animation) {
            Log.v("TEST","translateUp onAnimationEnd");
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationStart(Animation animation) {
            Log.v("TEST","translateUp onAnimationStart");
        }}
    );

If the customView is added to an activity, these code works fine!

When the customView is added to a WindowManager, the Log inside the onAnimationStart didn't show but the Log inside the Runnable can be shown.

Can anybody tells how to do animation on a view that is added to the WindowManager?

Mr.1
  • 121
  • 1
  • 6

4 Answers4

11

You should animate the view LayoutParameters. For example I use a method to update the view layout:

    public void updateViewLayout(View view, Integer x, Integer y, Integer w, Integer h){
    if (view!=null) {
        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) view.getLayoutParams();

        if(x != null)lp.x=x;
        if(y != null)lp.y=y;
        if(w != null && w>0)lp.width=w;
        if(h != null && h>0)lp.height=h;

        mWindowService.updateViewLayout(view, lp);
    }
}

Obviously mWindowService is context.getSystemService(Context.WINDOW_SERVICE). I trigger this method in the animation:

    public static void overlayAnimation(final View view2animate, int viewX, int endX) {
    ValueAnimator translateLeft = ValueAnimator.ofInt(viewX, endX);
    translateLeft.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            int val = (Integer) valueAnimator.getAnimatedValue();
            updateViewLayout(view2animate, val, null, null, null);

        }
    });
    translateLeft.setDuration(ANIMATION_DURATION);
    translateLeft.start();
}
Santacrab
  • 3,165
  • 2
  • 25
  • 31
8

I was facing similar problem with a View attached to WindowManager.Try adding ViewGroup to WindoManager than View directly. It should work.

Dusi
  • 81
  • 1
  • 2
  • 1
    You mean add the view to a viewgroup and then add the viewgroup to windowmanager? – Tushar Nallan Dec 03 '14 at 17:16
  • @alex how did you solve? I included an `ImageView` inside a `FrameLayout`, but now when I animate my `ImageView`, it goes off the bounds of the `FrameLayout`, so it is not visible anymore – user2340612 Nov 23 '15 at 23:11
0

windowManager need a animation by android system. so the custom animation will not work

Raghav Sood
  • 81,899
  • 22
  • 187
  • 195
Jian Wu
  • 31
  • 2
0

I had a problem.

When i use updateViewLayout in onAnimationUpdate, and i set the LayoutParams's width, the animation has dropped frames.

But i set the LayoutParams's x or y, the animation is ok.

like the below code:

        mViewWidth = 800;
        mViewHeight = 800;
        final int oldX = mFloatWindowParams.x;
        final int oldWidth = mFloatWindowParams.width;
        final int oldHeight = mFloatWindowParams.height;
        final int deltaWidth = mViewWidth - oldWidth;
        final int deltaHeight = mViewHeight - oldHeight;
        final boolean isWidthLarger = deltaWidth > deltaHeight;
        int first = isWidthLarger ? oldWidth : oldHeight;
        int end = isWidthLarger ? mViewWidth : mViewHeight;
        ValueAnimator va = ValueAnimator.ofInt(first, end);

        va.setDuration(1000);
        va.setInterpolator(new LinearInterpolator());
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (Integer) animation.getAnimatedValue();
                float fraction = animation.getAnimatedFraction();
                Log.i("onAnimationUpdate", value + "");
                if (isWidthLarger) {
                    mFloatWindowParams.width = value;
                    mFloatWindowParams.height = oldHeight + (int) (deltaHeight * fraction);
                } else {
                    mFloatWindowParams.width = oldWidth + (int) (deltaWidth * fraction);
                    mFloatWindowParams.height = value;
                }
                mFloatWindowParams.x = oldX - (int) (deltaWidth * fraction);

                mWindowManager.updateViewLayout(mRootView, mFloatWindowParams);
            }
        });
        va.start();