打开时的抽屉项目动画
Drawer item animation when opened
我使用 DrawerLayout 创建了一个抽屉,其中包含带有项目的 RecyclerView。我还在 RecyclerView 上附加了一个 layoutAnimation,以便在打开抽屉时让物品从侧面进入。这在第一次工作时很有效,但在第二次打开抽屉时,一切都已经就位。每次打开抽屉时,我都希望 layoutAnimation 为 运行。
到目前为止我尝试的是自定义 ActionBarDrawerToggle(无论如何我都需要那个),并添加以下内容:
@Override
public void onDrawerOpened(final View drawerView) {
super.onDrawerOpened(drawerView);
final RecyclerView recyclerView =
(RecyclerView) drawerView.findViewById(R.id.drawer_content);
if (recyclerView != null) {
recyclerView.startLayoutAnimation();
}
}
有点像,因为它重新运行动画,但是打开抽屉时所有物品都在那里,然后它们消失,然后动画开始。
有人知道如何在每次关闭抽屉时 "reset" 抽屉项目视图吗?
不确定是否需要这些,但无论如何我都会包含它们
<--! layout_animation.xml -->
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/slide_from_right"
android:delay="15%"
android:animationOrder="normal"
/>
<--! slide_from_right.xml -->
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100%p"
android:interpolator="@android:anim/decelerate_interpolator"
android:toXDelta="0"
/>
经过更多测试后我找到了解决方案,也许不是最漂亮的解决方案,但它确实有效。通过在抽屉关闭时隐藏内容然后在开始动画之前再次使其可见解决了我遇到的问题:
private boolean mFirstDrawerOpen = true;
private boolean mAnimationScheduled;
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
// The framework handles the first animation
if (mIsFirstDrawerOpen) {
mIsFirstDrawerOpen = false;
return;
}
final RecyclerView recyclerView =
(RecyclerView) drawerView.findViewById(R.id.drawer_content);
if (mAnimationScheduled && recyclerView != null) {
recyclerView.setVisibility(View.VISIBLE);
recyclerView.startLayoutAnimation();
mAnimationScheduled = false;
} else if (slideOffset == 0f) {
// Handles the case when the drawer is not completly opened and then closed,
// which does not trigger onDrawerClosed()
mAnimationScheduled = true;
}
}
@Override
public void onDrawerOpened(final View drawerView) {
super.onDrawerOpened(drawerView);
mAnimationScheduled = false;
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
mAnimationScheduled = true;
final RecyclerView recyclerView =
(RecyclerView) drawerView.findViewById(R.id.drawer_content);
if (recyclerView != null) {
recyclerView.setVisibility(View.INVISIBLE);
}
}
更新:
之前的答案没有处理抽屉被拖到一半打开然后关闭的情况,因为如果抽屉没有完全打开则不会调用 onDrawerClosed
。为了解决这个问题,我将大部分代码从 onDrawerOpen
移到了 onDrawerSlide()
并做了一些修改。
我遇到了与@patrick-iv 相同的问题,想知道其他人是如何解决的。我想出了将以下代码添加到 onDrawerStateChanged
侦听器。
boolean drawerOpen = drawer.isDrawerOpen(GravityCompat.START);
_drawerTopMenu.setVisibility(drawerOpen ? View.VISIBLE : View.INVISIBLE);
if (newState == DrawerLayout.STATE_SETTLING && !drawerOpen)
_drawerTopMenu.startLayoutAnimation();
我使用 DrawerLayout 创建了一个抽屉,其中包含带有项目的 RecyclerView。我还在 RecyclerView 上附加了一个 layoutAnimation,以便在打开抽屉时让物品从侧面进入。这在第一次工作时很有效,但在第二次打开抽屉时,一切都已经就位。每次打开抽屉时,我都希望 layoutAnimation 为 运行。
到目前为止我尝试的是自定义 ActionBarDrawerToggle(无论如何我都需要那个),并添加以下内容:
@Override
public void onDrawerOpened(final View drawerView) {
super.onDrawerOpened(drawerView);
final RecyclerView recyclerView =
(RecyclerView) drawerView.findViewById(R.id.drawer_content);
if (recyclerView != null) {
recyclerView.startLayoutAnimation();
}
}
有点像,因为它重新运行动画,但是打开抽屉时所有物品都在那里,然后它们消失,然后动画开始。
有人知道如何在每次关闭抽屉时 "reset" 抽屉项目视图吗?
不确定是否需要这些,但无论如何我都会包含它们
<--! layout_animation.xml -->
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/slide_from_right"
android:delay="15%"
android:animationOrder="normal"
/>
<--! slide_from_right.xml -->
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100%p"
android:interpolator="@android:anim/decelerate_interpolator"
android:toXDelta="0"
/>
经过更多测试后我找到了解决方案,也许不是最漂亮的解决方案,但它确实有效。通过在抽屉关闭时隐藏内容然后在开始动画之前再次使其可见解决了我遇到的问题:
private boolean mFirstDrawerOpen = true;
private boolean mAnimationScheduled;
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
// The framework handles the first animation
if (mIsFirstDrawerOpen) {
mIsFirstDrawerOpen = false;
return;
}
final RecyclerView recyclerView =
(RecyclerView) drawerView.findViewById(R.id.drawer_content);
if (mAnimationScheduled && recyclerView != null) {
recyclerView.setVisibility(View.VISIBLE);
recyclerView.startLayoutAnimation();
mAnimationScheduled = false;
} else if (slideOffset == 0f) {
// Handles the case when the drawer is not completly opened and then closed,
// which does not trigger onDrawerClosed()
mAnimationScheduled = true;
}
}
@Override
public void onDrawerOpened(final View drawerView) {
super.onDrawerOpened(drawerView);
mAnimationScheduled = false;
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
mAnimationScheduled = true;
final RecyclerView recyclerView =
(RecyclerView) drawerView.findViewById(R.id.drawer_content);
if (recyclerView != null) {
recyclerView.setVisibility(View.INVISIBLE);
}
}
更新:
之前的答案没有处理抽屉被拖到一半打开然后关闭的情况,因为如果抽屉没有完全打开则不会调用 onDrawerClosed
。为了解决这个问题,我将大部分代码从 onDrawerOpen
移到了 onDrawerSlide()
并做了一些修改。
我遇到了与@patrick-iv 相同的问题,想知道其他人是如何解决的。我想出了将以下代码添加到 onDrawerStateChanged
侦听器。
boolean drawerOpen = drawer.isDrawerOpen(GravityCompat.START);
_drawerTopMenu.setVisibility(drawerOpen ? View.VISIBLE : View.INVISIBLE);
if (newState == DrawerLayout.STATE_SETTLING && !drawerOpen)
_drawerTopMenu.startLayoutAnimation();