I am doing a custom android build, in which my Service adds a View on top of every app. 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 am able to add the view successfully. I am animating the view using
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 300);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX).start();
I am seeing the view animate, but not the window. The transparent window where the view used to be, is not animating. This is same behavior as described in Android Property Animation
Another disadvantage of the view animation system is that it only modified where the View was drawn, and not the actual View itself. For instance, if you animated a button to move across the screen, the button draws correctly, but the actual location where you can click the button does not change, so you have to implement your own logic to handle this.
How do i animate the window along with the view?
Thanks
You have two options to achieve this (keeping the user's touch feedback coherent with the View
's position):
Create a transparent container (like a FrameLayout
) big enough to contains your View
plus its animation offset (in your case with an height of 366+300 px). In this way, you will add the container to the Window
, while the View
stays inside the container and can be animated/traslated.
Move the absolute position of your View on the screen, creating a sort of custom animation; you just need to set the mParams.x
value dynamically using a ValueAnimator
or, if you want more bounciness, using a spring effect through the Rebound library. I suggest you the last one, it's really fancy!
Here's an (untested) example 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 add the Rebound's compile statement in your dependencies first:
// Gradle dependency on Rebound
dependencies {
compile 'com.facebook.rebound:rebound:0.3.8'
}
You could make it so that your window fills the entire screen by removing the height and width from the window params. If you want to control the view size, set it in your layout instead.
Otherwise, you can use a ValueAnimator
and repeatedly call WindowManager
's 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);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With