我正在进行一个自定义的android构建,其中我的服务在每个应用程序的顶部添加了一个视图。使用以下代码:
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);
我能够成功添加视图。我正在使用设置视图动画
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 300);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX).start();
我看到的是动画视图,但不是窗口。视图所在的透明窗口没有设置动画。这与Android属性动画中描述的行为相同
视图动画系统的另一个缺点是,它只修改了绘制视图的位置,而不是实际的视图本身。例如,如果你设置了一个按钮在屏幕上移动的动画,按钮会正确绘制,但你可以点击按钮的实际位置不会改变,所以你必须实现自己的逻辑来处理这个问题。
如何设置窗口和视图的动画?
感谢
有两个选项可以实现这一点(保持用户的触摸反馈与View
的位置一致):
-
创建一个足够大的透明容器(如
FrameLayout
),以包含View
及其动画偏移(在您的情况下,高度为366+300 px)。通过这种方式,可以将容器添加到Window
中,而View
则保留在容器中,并且可以设置动画/平移。 -
移动视图在屏幕上的绝对位置,创建一种自定义动画;您只需要使用
ValueAnimator
动态设置mParams.x
值,或者,如果您想要更多的弹跳力,可以通过回弹库使用弹簧效果。我建议你最后一个,它真的很好看!
这里有一个(未经测试)使用反弹的例子:
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);
请记住,您需要首先在依赖项中添加Rebound的编译语句:
// Gradle dependency on Rebound
dependencies {
compile 'com.facebook.rebound:rebound:0.3.8'
}
您可以通过从窗口参数中删除高度和宽度来填充整个屏幕。如果要控制视图大小,请在布局中进行设置。
否则,您可以使用ValueAnimator
并重复调用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);
}
});
请尝试以下操作:
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);
并保持动画myView就像你做
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 300);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX).start();
通知设置宽度&XML文件中视图的高度-R.layout.myView