Animating an Android window with a view

I am making a custom Android build in which my Service adds a view on top of each application. Using the following code:

WindowManager mWM = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); mParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); mParams.height = 117; mParams.width = 366; View myView = inflater.inflate(R.layout.myView,null); mWM.addView(myView, mParams); 

I can successfully add a view. I am animating a view using

 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 300); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX).start(); 

I see a view animation, but not a window. The transparent window where the image used to be is not animated. This is the same behavior as described in Android Animation Animation.

Another drawback of the view animation system is that it only changed the place where the View was displayed, and not the actual view. For example, if you animated a button to move around the screen, the button draws correctly, but the actual place where you can click the button does not change, so you need to implement your own logic to handle this.

How do I animate a window with a view?

thanks

+5
source share
3 answers

You have two options for achieving this goal (maintaining user feedback consistent with the View position):

  • Create a transparent container (e.g. FrameLayout ) so that it contains your View plus its animation offset (in your case, with a height of 366 + 300 pixels). Thus, you add the container to the Window , and the View remains inside the container and can be animated / traslated.

  • Move the absolute position of your view on the screen , creating some kind of custom animation; you just need to set the value of mParams.x dynamically using ValueAnimator or, if you need more bounciness, using the spring effect via Rebound . I offer you the last, it is really interesting!

Here's an example (untested) using Rebound:

 SpringSystem springSystem = SpringSystem.create(); Spring spring = springSystem.createSpring(); final int originalPos = mParams.x; final int offset = 300; spring.addListener(new SimpleSpringListener() { @Override public void onSpringUpdate(Spring spring) { float value = (float) spring.getCurrentValue(); mParams.x = originalPos + ((int) value*offset) mWM.updateViewLayout(myView, mParams); } }); spring.setEndValue(1); 

Remember that you need to first add the Rebound compilation statement to your dependencies:

 // Gradle dependency on Rebound dependencies { compile 'com.facebook.rebound:rebound:0.3.8' } 
+2
source

You can do this so that your window fills the entire screen, removing the height and width from the window settings. If you want to control the size of the view, set it in your layout.


Otherwise, you can use ValueAnimator and re-call WindowManager updateViewLayout :

 ValueAnimator va = ValueAnimator.ofInt(mParams.x, 300); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { Integer value = (Integer) animation.getAnimatedValue(); mParams.x = value.intValue(); mWM.updateViewLayout(myView, mParams); } }); 
+1
source

Try the following:

 WindowManager mWM = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); mParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); mParams.gravity = Gravity.TOP | Gravity.LEFT; mParams.x = 0; mParams.y = 0; View myView = inflater.inflate(R.layout.myView,null); LinearLayout parent = new LinearLayout(context); parent.addView(myView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); mWM.addView(parent, mParams); 

And save the myView animation as you did

 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 300); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX).start(); 

Notification Set the width and height of the view in the XML file - R.layout.myView

+1
source

Source: https://habr.com/ru/post/1235572/


All Articles