Make clear about addFlags and setFlags in android.view.Window class
Asked Answered
P

2

11

I know what setFlags does is replacing the old flags with the new ones. And addFlags is appending more flag. I'm just confused why are the arguments in setFlags method that I've seen usually the same? For example:

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

After taking a look at android.view.Window class, I'm not clear that why they must do many binary operators (NOT, AND, OR). What is the purpose of this?

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

One more question, what is the difference between

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

and

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

and

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

and

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

and

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

Any help would be appreciated.

Poundage answered 17/12, 2017 at 11:28 Comment(0)
B
19

The binary operators are because the field is a bitfield. They use a single integer to hold a lot of settings, and each settings are assigned to different bits. You then use binary operations to combine them and set the bits correctly. This is a common hardware technique, its very space efficient. Generally you'll turn on a bit (a setting) by using OR on it, and remove it by ANDing its inverse. Both of these operations leave the rest of the settings unchanged.

You would never see setFlags(FOO | FOO), because its redundant. All that happens is FOO would be set. You would see setFlags(FOO | BAR), which would set both FOO and BAR.

When you see setFlags(FOO, FOO)- the second parameter is a mask. It allows you to turn fields on and off at the same time, and only the bits in the mask will change. SO any other setting will be kept as it was. The math is basically ((getFlags &~mask) | (value & mask)). You'll see the same thing in both values if you only want to change certain settings, and you want to turn them all on. setFlags(x,x) is equivalent to addFlags(x)

Babbling answered 17/12, 2017 at 11:39 Comment(4)
You're a great teacher to me. However, I had to read wiki to comprehend your answer cause it is out of my knowledge :) I still have a little confusion. Could you give me an example using setFlags which have 2 different arguments? And I would be happy if you could explain that example.Poundage
To turn off a flag easily. setFlags(0, FOO) will turn off foo. setFlags(FOO, FOO | BAR) will turn on foo and off bar.Babbling
Using clearFlags(FOO) is more clearly than setFlags(0, FOO). Could you explain in more detail why setFlags(FOO, FOO | BAR) will turn on foo and off bar? How about setFlags(FOO, BAR)?Poundage
You can edit the answer so I can mark it when I'm clearPoundage
N
5

Look at the source of 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);
}

So addFlags is the same as setFlags but more convenient

Notions answered 9/3, 2019 at 7:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.