为视图平滑隐藏/显示动画并填充空白空间
我试图在一些DP滚动后将视图设置为动画并将其隐藏,并且我将所有内容都设置为正常,但问题在于当它弹出时您在应该触发动画的Y值之前或之后缓慢滚动。为视图平滑隐藏/显示动画并填充空白空间
我认为轻弹是因为我有它的可见性设置为过去了,更新其他视图match_parent,它不会只用TraslationY工作:
view.animate()
.translationY(-view.getBottom())
.alpha(0)
.setDuration(HEADER_HIDE_ANIM_DURATION)
.setInterpolator(new DecelerateInterpolator());
我试图设置布局相对和View 2作为match_parent来看看我是否能避免可见性改变,但它没有工作...
我已经实现了从谷歌I/O 2014 BaseActivity.java文件所需的所有代码: https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java#L17
而动画的作品......但我认为,因为我的customview不是具有叠加属性的动作条,所以customview不会离开,下面的LinearLayout将不会填充空白空间(没有)。
因此,我使它与animationlistener一起工作,并在动画结束时设置自定义视图的可见性消失,但当您接近预期的触发动画的Y点时,它会以可怕的方式轻弹(轻弹为自定义视图可视性消失了,下面的LinearLayout需要调整自己的大小以填充空白区域,并且如果您在那里缓慢滚动,则会很快重复)。
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:animateLayoutChanges="true">
<com.project.app.layouts.TabsLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tabs">
<FrameLayout
android:id="@+id/content_frame_header"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="@android:color/white"/>
</LinearLayout>
</RelativeLayout>
有没有办法做到这一点时,它不是一个动作条?
编辑: 添加关于如何缓慢滚动Y点触发动画以隐藏/显示时它将如何弹出的注释。
我建议你在你的Manifest文件中使用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),但仍可以使用ViewPropertyAnimatorCompat
我有一个FrameLayout,它具有标题视图和主视图,标题视图在前面。
<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>
一旦视图被测量(发布一个可运行的onResume期间)予设定的主视图的topPadding成为报头的高度。
在隐藏和显示动画中,我添加了一个更新侦听器,并在其中更新了主视图的顶部填充为标题的高度+ Y上的转换。
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);
}
});
这使得它更平滑一些,因为填充与翻译一起被更新。
实际上,使用ViewPropertyAnimatorCompat设置AnimationListener不起作用。监听器永远不会被调用,所以为了向下兼容,我选择了这个解决方案,不优雅,但至少在预奇巧设备的工作:
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);
变量mAnimatingHeader使用AnimationListener(工作)更新
我建议您在一张纸上绘制您想要的动画步骤,并将其作为图像张贴在这里,或者您可以使用一些绘图程序。通过这种方式,我们将展现您所期待的最终效果。 – vovahost 2014-11-03 23:31:58
很简单,只需要一个视图1消失并查看2填充视图1左侧的空白区域。就像当您在Google I/O 2014中向下滚动操作栏时隐藏操作栏,但使用自定义视图而不是操作栏时。 – Motheus 2014-11-04 00:53:51
也许这很容易实现,但很难理解视图1和视图2如何在布局中定位。你提到将可见性设置消失,但我们没有看到任何代码。如果你想得到一个很好的答案,那么请添加一些代码,也许草图。 – vovahost 2014-11-04 08:24:45