Анимированный вид добавлен в WindowManager

У меня есть представление (customView), добавленное в 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);

Внутри пользовательского представления я вызову анимацию перевода при нажатии кнопки закрытия.

//// Это обработчик анимации ////

final Handler translateHandler = new Handler();

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

//// Это прослушиватель кнопки закрытия////

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

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

//// Это анимация перевода вверх ////

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

Если customView добавлен в действие, этот код работает нормально!

Когда customView добавляется в WindowManager, журнал внутри onAnimationStart не отображается, но может отображаться журнал внутри Runnable.

Может ли кто-нибудь сказать, как сделать анимацию в представлении, добавленном в WindowManager?


person Mr.1    schedule 29.12.2011    source источник
comment
У вас есть какое-нибудь решение для этого? Поделитесь пожалуйста, у меня такая же проблема   -  person om252345    schedule 09.05.2012


Ответы (4)


Вы должны анимировать представление LayoutParameters. Например, я использую метод для обновления макета представления:

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

Очевидно, mWindowService — это context.getSystemService(Context.WINDOW_SERVICE). Я запускаю этот метод в анимации:

    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();
}
person Santacrab    schedule 19.06.2014
comment
Круто, это способ сделать это правильно, не оборачивая представление в ViewGroup. - person qbasso; 12.09.2014
comment
Это единственное решение, которое сработало для меня, спасибо! Я пытался использовать TranslateAnimation, но не играл в кости. - person Tyler Pfaff; 29.04.2016

Я столкнулся с аналогичной проблемой с представлением, прикрепленным к WindowManager. Попробуйте добавить ViewGroup в WindoManager, а не представление напрямую. Он должен работать.

person Dusi    schedule 29.03.2012
comment
Спасибо за подсказку. Работает на меня :) - person alex; 08.04.2014
comment
Вы имеете в виду добавить представление в группу просмотра, а затем добавить группу просмотра в оконный менеджер? - person Tushar Nallan; 03.12.2014
comment
@alex как ты решил? Я включил ImageView внутри FrameLayout, но теперь, когда я анимирую свой ImageView, он выходит за границы FrameLayout, поэтому его больше не видно. - person user2340612; 24.11.2015

windowManager нужна анимация системой андроид. поэтому пользовательская анимация не будет работать

person Jian Wu    schedule 29.08.2012

У меня была проблема.

Когда я использую updateViewLayout в onAnimationUpdate и устанавливаю ширину LayoutParams, анимация пропускает кадры.

Но я установил x или y LayoutParams, анимация в порядке.

как в приведенном ниже коде:

        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();
person carroll cai    schedule 24.09.2020