在android.view.Window类中明确addFlags和setFlags

问题描述 投票:2回答:2

我知道setFlags做的是用新的标志替换旧标志。并且addFlags会附加更多标志。我只是困惑为什么setFlags方法中的参数我通常看到的相同?例如:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
//or
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

看了android.view.Window类后,我不清楚为什么他们必须做很多二元运算符(NOT,AND,OR)。这样做的目的是什么?

public void setFlags(int flags, int mask) {
        final WindowManager.LayoutParams attrs = getAttributes();
        attrs.flags = (attrs.flags & ~mask) | (flags & mask);
        mForcedWindowFlags |= mask;
        dispatchWindowAttributesChanged(attrs);
    }

还有一个问题,有什么区别

//argument is a flag
getWindow().addFlags(flag1);

//argument is the result of OR operator of 2 identical flags
getWindow().addFlags(flag1 | flag1);

//argument is the result of OR operator of 2 different flags
getWindow().addFlags(flag1 | flag 2);

//argument is the result of AND operator of 2 identical flags
getWindow().addFlags(flag1 & flag1);

//argument is the result of AND operator of 2 different flags
getWindow().addFlags(flag1 & flag2);

任何帮助,将不胜感激。

android android-windowmanager android-window
2个回答
7
投票

二元运算符是因为该字段是位域。它们使用单​​个整数来保存大量设置,并且每个设置都分配给不同的位。然后,您可以使用二进制操作来组合它们并正确设置位。这是一种常见的硬件技术,其空间效率非常高。通常你会在它上面使用OR来打开一个位(一个设置),并通过ANDing它的逆来删除它。这两个操作都保持其余设置不变。

你永远不会看到setFlags(FOO | FOO),因为它是多余的。所有这一切都将被设置为FOO。你会看到setFlags(FOO | BAR),它会同时设置FOO和BAR。

当你看到setFlags(FOO,FOO)时 - 第二个参数是一个掩码。它允许您同时打开和关闭字段,并且只有掩码中的位会发生变化。所以任何其他设置都将保持不变。数学基本上是((getFlags&~mask)|(value&mask))。如果您只想更改某些设置,并且想要全部打开它们,您会在两个值中看到相同的内容。 setFlags(x,x)相当于addFlags(x)


0
投票

看看Window.java的来源

/**
 * Convenience function to set the flag bits as specified in flags, as
 * per {@link #setFlags}.
 * @param flags The flag bits to be set.
 * @see #setFlags
 * @see #clearFlags
 */
public void addFlags(int flags) {
    setFlags(flags, flags);
}

所以addFlagssetFlags一样但更方便

© www.soinside.com 2019 - 2024. All rights reserved.