在recyclerview中单击某个项目时,我会调用它
appbar.removeView(tabs)
This视频显示了会发生什么
它似乎完全删除TabLayout没有动画,然后将其添加回来,然后使用动画删除它。我放慢了转变速度,以显示它的作用。
当像这样添加它们时也会发生这种情况
if (tabs.parent != null) {
(tabs.parent as ViewGroup).removeView(tabs)
}
appbar.addView(tabs)
appbar.setExpanded(true, true)
这是我的布局
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
app:elevation="0dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/MyToolbar"
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextAppearance="@style/TabText"
android:layout_marginRight="@dimen/small_spacing"
android:layout_marginLeft="@dimen/small_spacing"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabIndicatorHeight="2dp"
app:layout_scrollFlags="enterAlways"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/appbar"
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
<***.***.CustomViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
那么发生了什么?
除了你提到的闪光之外,一切似乎都能正常工作。我带了Chris Banes的Cheese Square应用程序并进行了一些修改以复制你所看到的内容。单击FAB将删除并添加选项卡。
这是我想出的视频。
这是删除TabLayout
时问题的屏幕截图。如您所见,RecyclerView
覆盖了appbar。
这是当TabLayout
重新加入时问题的屏幕截图。在这里你可以看到RecyclerView
在添加视图后向下移动到它的位置。
消失的TabLayout
的布局过渡正在与LayoutTransition
完成。要进行有效的过渡,LayoutTransition
必须确定最终布局的样子,以便构建一组动画。这需要在过渡后布置屏幕的样子。似乎在动画运行之前短暂显示最终布局。 (我的猜测。)这可能是竞争条件,也可能与this caveat有关:
此类以及容器的关联XML标志animateLayoutChanges =“true”,提供了一个简单的实用程序,用于在简单情况下自动更改。由于各种布局级别的相互关系,在嵌套视图层次结构的多个级别使用LayoutTransition可能不起作用。此外,在添加或删除项目的同时滚动的容器可能不适合此实用程序,因为LayoutTransition计算的前/后位置可能与动画完成时的实际位置不匹配在动画运行时滚动容器。您可以通过将CHANGE_APPEARING和CHANGE_DISAPPEARING动画设置为null来禁用“更改”动画,并适当地设置其他动画的startDelay来解决该特定问题。
对能够弄清楚发生了什么的人的称赞和声誉。 (这个问题可能是LayoutTransition
代码中以下神秘评论中提到的工件:)
/**
* Controls whether changing animations automatically animate the parent hierarchy as well.
* This behavior prevents artifacts when wrap_content layouts snap to the end state as the
* transition begins, causing visual glitches and clipping.
* Default value is true.
*/
private boolean mAnimateParentHierarchy = true;
怎么解决?
我建议你完全抛弃LayoutTransitions
(android:animateLayoutChanges="false"
)并继续使用TransitionManager
。
我们将使用方便的方法TransitionManager#beginDelayedTransition
:
beginDelayedTransition
void beginDelayedTransition(ViewGroup sceneRoot,Transition transition)
在调用此方法和下一个渲染帧之间,为给定场景根中的所有更改定义的新场景设置动画的便捷方法。调用此方法会导致TransitionManager捕获场景根中的当前值,然后发布请求以在下一帧上运行转换。此时,将捕获场景根中的新值,并且将更改动画的更改。无需创建场景;它是由调用此方法与转换开始时的下一帧之间发生的更改所暗示的。
这是我删除和添加选项卡的代码。确保设置animateLayoutChanges="false"
。
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mTabsAdded) {
// Get rid of the indicator due to an on-screen artifact.
tabs.setSelectedTabIndicatorHeight(0);
TransitionSet set = new TransitionSet()
.addTransition(new Fade(OUT))
.addTransition(new ChangeBounds());
TransitionManager.beginDelayedTransition(layout, set);
mAppBar.removeView(tabs);
} else {
// Add tab indicator back in.
int indicatorHeight = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 2,
getResources().getDisplayMetrics());
tabs.setSelectedTabIndicatorHeight(indicatorHeight);
TransitionSet set = new TransitionSet()
.addTransition(new Fade(IN))
.addTransition(new ChangeBounds());
TransitionManager.beginDelayedTransition(layout, set);
mAppBar.addView(tabs);
}
mTabsAdded = !mTabsAdded;
}
});
从视频看,根据TabLayout
看起来有三个片段加载。 MyPhotosFragment
,MyAlbumsFragment
和MyFavouritesFragment
。
如果我理解正确,你将TabLayout
放在活动中,这三个片段直接加载到活动中。当抽屉上选择“隐藏相册”时,会显示/添加appbar,并在选择其他项目时隐藏/删除它。
你应该做的是制作一个充当容器的新片段。我们称之为HiddenAlbumsFragment
。然后你应该从活动中删除TabLayout
和ViewPager
并将其放在HiddenAlbumsFragment
内。单击选项卡项时,HiddenAlbumsFragment
应将相应的片段加载为子片段。然后,当您从抽屉中选择一个时,将HiddenAlbumsFragment替换为另一个,则tablayout将自动消失。
你可以用这样的动画隐藏标签布局。
tabLayout.animate().scaleY(0).setInterpolator(new AccelerateInterpolator()).start();
我还没有测试过。如果您对此有任何疑问,请发表评论。可能这应该工作。