8

我知道 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 | flag2);

//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);

任何帮助,将不胜感激。

4

2 回答 2

17

二元运算符是因为该字段是位字段。它们使用一个整数来保存很多设置,并且每个设置都分配给不同的位。然后,您使用二进制操作将它们组合并正确设置位。这是一种常见的硬件技术,非常节省空间。通常,您将通过对其使用 OR 来打开一点(设置),并通过 ANDing 其逆来删除它。这两个操作都保持其余设置不变。

你永远不会看到 setFlags(FOO | FOO),因为它是多余的。所发生的只是设置了 FOO。您会看到 setFlags(FOO | BAR),它将同时设置 FOO 和 BAR。

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

于 2017-12-17T11:39:48.923 回答
4

查看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);
}

soaddFlags一样setFlags但是更方便

于 2019-03-09T07:50:05.463 回答