android – 使用removeView()从AppBarLayout中删除TabLayout时出现故障
作者:互联网
在recyclerview中单击某个项目时,我会调用它
appbar.removeView(标签)
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向下移动到其位置.
正在使用LayoutTransition完成消失的TabLayout的布局转换.要进行有效的转换,LayoutTransition必须确定最终布局的外观,以便构建一组动画.这需要在过渡后布置屏幕的样子.似乎在动画运行之前短暂显示最终布局. (我的猜测.)这可能是竞争条件,或者可能与this caveat有关:
This class, and the associated XML flag for containers, animateLayoutChanges=”true”, provides a simple utility meant for automating changes in straightforward situations. Using LayoutTransition at multiple levels of a nested view hierarchy may not work due to the interrelationship of the various levels of layout. Also, a container that is being scrolled at the same time as items are being added or removed is probably not a good candidate for this utility, because the before/after locations calculated by LayoutTransition may not match the actual locations when the animations finish due to the container being scrolled as the animations are running. You can work around that particular issue by disabling the ‘changing’ animations by setting the CHANGE_APPEARING and CHANGE_DISAPPEARING animations to null, and setting the startDelay of the other animations appropriately.
对能够弄清楚发生了什么的人的称赞和声誉. (此问题可能是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)Convenience method to animate to a new scene defined by all changes within the given scene root between calling this method and the next rendering frame. Calling this method causes TransitionManager to capture current values in the scene root and then post a request to run a transition on the next frame. At that time, the new values in the scene root will be captured and changes will be animated. There is no need to create a Scene; it is implied by changes which take place between calling this method and the next frame when the transition begins.
这是我删除和添加选项卡的代码.确保设置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;
}
});
标签:android,android-tablayout,android-appbarlayout 来源: https://codeday.me/bug/20190527/1162225.html