Android 平滑隐藏/显示视图的动画和填充空白空间的第二个视图

Android 平滑隐藏/显示视图的动画和填充空白空间的第二个视图,android,android-animation,Android,Android Animation,我正在尝试设置一个视图的动画,并在一些DP被滚动后隐藏它,我将一切都做得很好,但问题是,当你在应该触发动画的Y值之前或之后缓慢滚动时,它会弹得很厉害 我认为这是因为我必须将它的可见性设置为Gone,并将另一个视图更新为match_parent,它不能仅与Traslation一起工作: view.animate() .translationY(-view.getBottom()) .alpha(0

我正在尝试设置一个视图的动画,并在一些DP被滚动后隐藏它,我将一切都做得很好,但问题是,当你在应该触发动画的Y值之前或之后缓慢滚动时,它会弹得很厉害

我认为这是因为我必须将它的可见性设置为Gone,并将另一个视图更新为match_parent,它不能仅与Traslation一起工作:

           view.animate()
                    .translationY(-view.getBottom())
                    .alpha(0)
                    .setDuration(HEADER_HIDE_ANIM_DURATION)
                    .setInterpolator(new DecelerateInterpolator());
我试图将布局设置为相对,并将2视为匹配父视图,以查看是否可以避免可见性更改,但它不起作用

我已经从Google I/O 2014 BaseActivity.java文件中实现了所有必需的代码:

而动画作品。。。但是我假设,由于我的customview不是一个具有覆盖属性的actionbar,customview不会离开,下面的LinearLayout也不会填充空白(没有)

因此,我使用animationlistener,在动画结束时将customview visibility设置为gone,但当您接近触发动画的预期Y点时,它将以可怕的方式闪烁(随着customview可见性消失,下面的LinearLayout需要调整自身大小以填充空白,如果在此处缓慢滚动,则会快速重复该操作)

XML:


当它不是actionbar时,有什么方法可以做到这一点吗

编辑:
添加了有关当您在Y点周围缓慢滚动以触发动画隐藏/显示时它将如何闪烁的注释。

我建议您在清单文件中使用android:hardwareAccelerated=“true”属性。它将使用设备的GPU绘制视图和动画。

我建议您检查
view.getBottom()的值
在这两种情况下(工作时和不工作时)。
可能是因为
view.getBottom()
返回的值非常大,所以它会闪烁。
在代码中添加此行:

Log.i("YourAppName", "view.getBottom(): -" + view.getBottom());
view.animate()
        .translationY(-view.getBottom())
        .alpha(0)
        .setDuration(HEADER_HIDE_ANIM_DURATION)
        .setInterpolator(new DecelerateInterpolator());

然后检查您的日志,看看这些值是否相同。

我用了一种稍有不同的方法。请注意,我使用的调用需要SDK 19(KitKat),但您仍然可以使用

我有一个框架布局,有标题视图和主视图,标题视图在前面

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fab="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <include layout="@layout/main_layout" android:id="@+id/main_layout" />
    <include layout="@layout/header_layout" android:id="@+id/header_layout" />
</FrameLayout>
这使得它更平滑一些,因为填充会随着翻译一起更新

实际上,使用ViewPropertyAnimatorCompat设置AnimationListener不起作用。从未调用该侦听器,因此为了向后兼容,我选择了此解决方案,虽然不优雅,但至少它在KitKat之前的设备上起作用:

final View mainView = findViewById(R.id.main_view);
Runnable mainUpdateRunnable = new Runnable() {          
    @Override
    public void run() {
        int top = (int) (header.getHeight()+header.getTranslationY());
        mainView.setPadding(0, top, 0, 0);
        if (mAnimatingHeader) {
            mainView.post(this);
        }
    }
};
mainView.post(mainUpdateRunnable);

使用AnimationListener(有效)更新变量mAnimatingHeader

我建议您在一张纸上画出您想要实现的动画步骤,并将其作为图像发布在这里,或者您可以使用一些绘图程序。这样我们就可以了解您想要的最终效果。很简单,只需让视图1消失,视图2填充视图1留下的空白。就像actionbar隐藏w一样当您在Google I/O 2014上向下滚动时,使用的是自定义视图,而不是actionbar。可能很容易实现,但很难理解视图1和视图2在布局中的位置。您谈到将可见性设置为gone,但我们看不到任何代码。如果您想得到一个好的答案,请添加一些代码,或者添加一个草图。Gi给我几分钟时间…这样更好,但你可以给我们一些屏幕截图或yuotube视频,两种情况:一种是当它工作时,另一种是当你看到它时。对不起,我忘了添加一个小评论。我想问题是,当你慢慢滚动通过触发动画的Y点时,会发生动画。如果你快速滚动就可以了。另外,我的minSDK是14,所以android:hardwareAccelerated默认为true。@你尝试过其他插值器吗?尝试在清单上添加加速属性,因为有时即使你的minSDK是14,它在默认情况下也不会启用14@Motheus我在另一个问题中找到了一些信息
final View header = findViewById(R.id. header_layout);              
header.animate()
 .translationY(-header.getBottom())
 .setDuration(200)
 .setInterpolator(new DecelerateInterpolator())
 .setUpdateListener(new AnimatorUpdateListener() {          
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int top = (int) (header.getHeight()+header.getTranslationY());
        findViewById(R.id.main_view).setPadding(0, top, 0, 0);
    }
 });
final View mainView = findViewById(R.id.main_view);
Runnable mainUpdateRunnable = new Runnable() {          
    @Override
    public void run() {
        int top = (int) (header.getHeight()+header.getTranslationY());
        mainView.setPadding(0, top, 0, 0);
        if (mAnimatingHeader) {
            mainView.post(this);
        }
    }
};
mainView.post(mainUpdateRunnable);