随着视图的变化,如何在Android中实现窗口动画

5

我正在进行一个自定义的安卓构建,其中我的服务在每个应用程序上方添加了一个视图。使用以下代码:

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被绘制的位置,而不是实际的View本身。例如,如果您将按钮动画移到屏幕上,按钮会正确绘制,但是单击按钮的实际位置不会改变,因此您需要实现自己的逻辑来处理这个问题。
如何同时动画窗口和视图?
谢谢。

你的 myView 布局是什么样子的? - tachyonflux
3个回答

2
您有两个选项来实现这一点(保持用户的触摸反馈与视图的位置相一致):
  1. 创建一个透明容器(如FrameLayout),足够大以包含您的View及其动画偏移量(在您的情况下,高度为366+300 px)。这样,您将向Window添加容器,而View仍然留在容器内并可以进行动画/平移。

  2. 在屏幕上移动您的View的绝对位置,创建一种自定义动画;您只需要使用ValueAnimator动态设置mParams.x值,或者如果您想要更多的弹性,则通过Rebound库使用弹簧效果。我建议您使用后者,它非常时尚!

以下是使用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);

请记得首先在您的依赖项中添加Rebound的编译语句:

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

1

如果您想让窗口填满整个屏幕,则可以从窗口参数中删除高度和宽度。如果您想控制视图大小,请在布局中设置。


否则,您可以使用 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);
    }
});

1

请试一下这个:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接