我在代码中设置了animateLayoutChanges = true,为我片段中的选项项设置动画。
当我打开PreferenceFragment时,我启用向上导航图标,然后在关闭它时禁用它,但它的行为方式很奇怪,在标题左侧留下了一种填充,其中NavigationIcon就是。< / p>
这是一个显示正在发生的事情的GIF:
你是否知道为什么会这样? 我在互联网上搜索得很远,但一无所获。
是否有以相同方式为这些项目设置动画的解决方法? 感谢。
答案 0 :(得分:2)
备注:我知道这个线程已经一年多了,但是很多人仍然迷失在这个问题上。
我花了好几个小时才终于解决这个问题,而解决方案实际上相对容易。
调用ActionBar.setDisplayHomeAsUpEnabled()或Toolbar.setNavigationIcon()时,工具栏将根据指定的值动态添加或删除导航视图
public void setNavigationIcon(@Nullable Drawable icon) {
if (icon != null) {
ensureNavButtonView();
if (!isChildOrHidden(mNavButtonView)) {
addSystemView(mNavButtonView, true);
}
} else if (mNavButtonView != null && isChildOrHidden(mNavButtonView)) {
removeView(mNavButtonView);
mHiddenViews.remove(mNavButtonView);
}
if (mNavButtonView != null) {
mNavButtonView.setImageDrawable(icon);
}
}
然后在onLayout中,它将检查是否存在导航按钮并对其进行布局。
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// more code before
if (shouldLayout(mNavButtonView)) {
if (isRtl) {
right = layoutChildRight(mNavButtonView, right, collapsingMargins,
alignmentHeight);
} else {
left = layoutChildLeft(mNavButtonView, left, collapsingMargins,
alignmentHeight);
}
}
// more code after. also mTitleTextView is laid out here
}
在布置每个视图后,工具栏还会增加左/右位置。这些值用作每个后续视图的偏移量。
要检查视图是否布局,请使用辅助功能:
private boolean shouldLayout(View view) {
return view != null && view.getParent() == this && view.getVisibility() != GONE;
}
通过xml中的代码或animateLayoutChanges设置layoutTransition时,我们会稍微改变行为。
让我们从我们从父级移除子级(ViewGroup代码)时发生的事情开始:
private void removeFromArray(int index) {
final View[] children = mChildren;
if (!(mTransitioningViews != null && mTransitioningViews.contains(children[index]))) {
children[index].mParent = null;
}
// more code after
}
您是否提到我们设置了转换后,孩子的父母没有为空?这很重要!
还请回忆一下上面的shouldLayout会做什么-它仅检查三种情况:
这是问题的根源-导航按钮已从工具栏中删除,但对此事件一无所知。
为了解决此问题,我们需要迫使工具栏认为不应布局视图。理想情况下,重写shouldLayout方法会很好,但是我们没有那么奢侈...因此,实现此目的的唯一方法是更改导航按钮的可见性。
class FixedToolbar(context: Context, attrs: AttributeSet?) : MaterialToolbar(context, attrs) {
companion object {
private val navButtonViewField = Toolbar::class.java.getDeclaredField("mNavButtonView")
.also { it.isAccessible = true }
}
override fun setNavigationIcon(icon: Drawable?) {
super.setNavigationIcon(icon)
(navButtonViewField.get(this) as? View)?.isGone = (icon == null)
}
}
现在,工具栏将知道不得布置导航按钮,并且所有动画都将按预期进行。
答案 1 :(得分:0)
我找到了一种解决方法来使工作过渡。
调用supportActionBar?.setDisplayHomeAsUpEnabled(false)
隐藏后退箭头按钮后,调用TransitionManager.beginDelayedTransition()方法手动触发转换。
// Hide the back arrow button
supportActionBar?.setDisplayHomeAsUpEnabled(false)
// Add a transition listener to the toolbar to set the toolbar title later
mToolbar.layoutTransition.addTransitionListener(object : LayoutTransition.TransitionListener {
override fun startTransition(transition: LayoutTransition?, container: ViewGroup?, view: View?, transitionType: Int) {}
override fun endTransition(transition: LayoutTransition?, container: ViewGroup?, view: View?, transitionType: Int) {
setToolbarTitle("Agenda")
mToolbar.layoutTransition.removeTransitionListener(this)
}
})
TransitionManager.beginDelayedTransition(mToolbar)