window background and translucent

Window background and translucent

涉及知识点:

Activity、Window、Dialog、View 相关知识点

前言:

发现很多同学在线上都会问到这个问题;遂,作此篇!

问题:

  1. windowBackground为透明时, windowIsTranslucent为false, Activity背景为何还是黑色,为什么不是透明?
  2. windowBackground为红色时, windowIsTranslucent为true, Activity背景还是红色,为什么不是透明?

解决:

windowBackground 、windowIsTranslucent顾名思义是Window属性,但是具体的实现是在哪里呢?是在RootView中———也就是DecorView类中

  1. 我们进入DecorView类中:
  2. 找到setWindowBackground方法
    public void setWindowBackground(Drawable drawable) {
        if (getBackground() != drawable) {
            setBackgroundDrawable(drawable);
            if (drawable != null) {
                mResizingBackgroundDrawable = enforceNonTranslucentBackground(drawable,
                        mWindow.isTranslucent() || mWindow.isShowingWallpaper());
            } else {
                mResizingBackgroundDrawable = getResizingBackgroundDrawable(
                        getContext(), 0, mWindow.mBackgroundFallbackResource,
                        mWindow.isTranslucent() || mWindow.isShowingWallpaper());
            }
            if (mResizingBackgroundDrawable != null) {
                mResizingBackgroundDrawable.getPadding(mBackgroundPadding);
            } else {
                mBackgroundPadding.setEmpty();
            }
            drawableChanged();
        }
    }

    我们可以看到enforceNonTranslucentBackground中使用到 Window.isTranslucent(),于是我们向下进一步寻找

  1. 找到 enforceNonTranslucentBackground
    /**
    * Enforces a drawable to be non-translucent to act as a background if needed, i.e. if the
    * window is not translucent.
    */
    private static Drawable enforceNonTranslucentBackground(Drawable drawable,
            boolean windowTranslucent) {
        if (!windowTranslucent && drawable instanceof ColorDrawable) {
            ColorDrawable colorDrawable = (ColorDrawable) drawable;
            int color = colorDrawable.getColor();
            if (Color.alpha(color) != 255) {
                ColorDrawable copy = (ColorDrawable) colorDrawable.getConstantState().newDrawable()
                        .mutate();
                copy.setColor(
                        Color.argb(255, Color.red(color), Color.green(color), Color.blue(color)));
                return copy;
            }
        }
        return drawable;
    }

    enforceNonTranslucentBackground中的大致逻辑:当windowTranslucent == false,enforceNonTranslucentBackground会强制将背景更改为不透明背景(PS: 即使windowBackground 是 透明的 )


未完待续。。。