Android 向后导航时工具栏变为半透明

Android Toolbar becomes translucent when navigating back

示例项目说明问题

https://github.com/justincpollard/TransparentToolbarExample

背景

我们有一个 Activity/Fragment 组合用于在我们的应用程序中显示内容。我们的用户能够在内容片段之间导航,这实际上是将这些 Activity/Fragment 组合放在另一个之上。点击硬件后退按钮或向上按钮只会显示之前的内容。

以下引用示例工程

当用户查看一段内容时,工具栏 (android.support.v7.widget.Toolbar) 及其文本开始透明。我们是这样完成的:

public void onCreateView(...) {
    ...
    toolbar = (Toolbar) v.findViewById(R.id.toolbar);
    ...
    actionBarDrawable = toolbar.getBackground();
    actionBarDrawable.setAlpha(0);
    actionBarText.setTextColor(Color.argb(0, 255, 255, 255));
    ...
}

如果用户滚动经过页面上的某个点,例如滚动等于工具栏高度的量,我们将工具栏背景和文本的 alpha 设置为从 0 到 255 的动画,基本上显示工具栏:

private void animateToolbar(final int start, final int finish) {
    toolbarIsAnimating = true;
    ValueAnimator animator = ValueAnimator.ofInt(start, finish);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
         toolbarAlpha = (int) animation.getAnimatedValue();
         actionBarDrawable.setAlpha(toolbarAlpha);
         actionBarText.setTextColor(Color.argb(toolbarAlpha, 255, 255, 255));
        if(toolbarAlpha == finish) {
          toolbarIsAnimating = false;
        }
       }
    });
    animator.setInterpolator(new DecelerateInterpolator());
    animator.setDuration(300);
    animator.start();
}

问题

当用户在滚动超过阈值点后从原始内容导航到另一内容时(即工具栏背景已动画显示),按 back/up 显示原始内容 Activity/Fragment组合,但工具栏是完全透明的。

为了在示例项目中进行说明,构建并打开应用程序,滚动到页面底部,然后按 "MORE CONTENT" 按钮。导航到第二个 Activity 后,请按后退按钮。请注意,工具栏是透明的,但标题文本仍然可见。

有没有人见过这个问题?我只在 Android 5.+ 上看到过它,但随着 5.+ 的采用率持续增长,这将成为一个更大的问题。

感谢您的帮助!

找到解决方案:

而不是

toolbar.getBackground().setAlpha();

您需要使用

toolbar.getBackground().mutate().setAlpha();

显然,默认情况下,可绘制对象之间共享状态,调用 mutate() 将使该特定可绘制对象不共享状态。

有趣的是,@Gricher 和我几乎同时找到了答案。我还没有审查他的回答,但这是我的:

无需处理从 toolbar.getBackground() 返回的 Drawable。您可以使用与我用来更改操作栏文本颜色的技术类似的技术来完成同样的事情。

将此用于 animateToolbar() 方法:

private void animateToolbar(final int start, final int finish) {
    toolbarIsAnimating = true;
    ValueAnimator animator = ValueAnimator.ofInt(start, finish);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
         toolbarAlpha = (int) animation.getAnimatedValue();
         toolbar.setBackgroundColor(Color.argb(toolbarAlpha, 56, 204, 255));
         actionBarText.setTextColor(Color.argb(toolbarAlpha, 255, 255, 255));
        if(toolbarAlpha == finish) {
          toolbarIsAnimating = false;
        }
       }
    });
    animator.setInterpolator(new DecelerateInterpolator());
    animator.setDuration(300);
    animator.start();
  }

关键是:

toolbar.setBackgroundColor(Color.argb(toolbarAlpha, 56, 204, 255));

也适用于 Android 6.+(目前的版本)。