Android设置变量值之——与或非(&、|、~)

https://github.com/NieJianJian/AndroidNotes,内容将持续更新,欢迎star。


Android常用与或非来添加和判断变量,比如,Window.java类中的一些变量:

public static final int FEATURE_NO_TITLE = 1;
public static final int FEATURE_PROGRESS = 2;
public static final int FEATURE_LEFT_ICON = 3;
public static final int FEATURE_RIGHT_ICON = 4;
public static final int FEATURE_INDETERMINATE_PROGRESS = 5;
public static final int FEATURE_CONTEXT_MENU = 6;
public static final int FEATURE_CUSTOM_TITLE = 7;
public static final int FEATURE_ACTION_BAR = 8;

上述为一些常量,如果我们想设置Activity为没有title的风格,就需要在Activity中如下调用:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE); // 1
    setContentView(R.layout.activity_main);
}

添加注释1处的代码,就可以设置设置没有title,具体会在Window.java中设置:

private int mFeatures;
public boolean requestFeature(int featureId) {
    final int flag = 1<<featureId;
    mFeatures |= flag;
    mLocalFeatures |= mContainer != null ? (flag&~mContainer.mFeatures) : flag;
    return (mFeatures&flag) != 0;
}

mFeatures是一个int类型的变量。

此时,我们传递到requestFeature中的参数为FEATURE_NO_TITLE,所以:

flag = 1 << featureId;
等价于 :flag = 1 << FEATURE_NO_TITLE;
等价于 :flag = 1 << 1;
等价于 :flag = 2// 二进制的 10

然后调用:

mFeatures |= flag;
等价于: mFeatures |= 2;
等价于: mFeatures = 2// 二进制10

如果在设置其他的效果,比如添加FEATURE_CONTEXT_MENU,

flag = 1 << featureId;
等价于 :flag = 1 << FEATURE_CONTEXT_MENU;
等价于 :flag = 1 << 6;
等价于 :flag = 64// 二进制的 1000000

然后调用:

mFeatures |= flag;
等价于: mFeatures = mFeatures | flag;
等价于: mFeatures = 2 | 64; 
等价于: mFeatures = 66// 二进制的1000010 

如果还想设置一个FEATURE_LEFT_ICON:

flag = 1 << featureId;
等价于 :flag = 1 << FEATURE_LEFT_ICON;
等价于 :flag = 1 << 3;
等价于 :flag = 8// 二进制的 1000

然后调用:

mFeatures |= flag;
等价于: mFeatures = mFeatures | flag;
等价于: mFeatures = 66 | 8; 
等价于: mFeatures = 74// 二进制的1001010 

此时,mFeatures的值为74,等价于二进制的:

1001010 

设置该mFeatures的参数有什么意义呢?主要是用来做一些判断:

比如,判断我们当前有没有设置FEATURE_NO_TITLE,可以执行下面的操作:

boolean b = (mFeatures & (1 << FEATURE_NO_TITLE)) != 0

上述的代码,等价于:

74 & 1 << 1

等价于二进制的如下两个数相与:

1001010
0000010

上述两个二进制的与的结果为0000010,也就是2,即不为0是满足的。

同理,我们要判断当前有没有设置FEATURE_RIGHT_ICON,可以执行下面的操作:

boolean b = (mFeatures & (1 << FEATURE_RIGHT_ICON)) != 0

等价于二进制的如下两个数相与:

1001010
0100000

上述两个二进制数相与的结果为0,所以当前没有设置FEATURE_RIGHT_ICON参数。


如果想要清除FEATURE_CONTEXT_MENU设置,该如何操作?那就是使用~

mFeatures &= ~(1 << FEATURE_CONTEXT_MENU)

上述代码等价于:

mFeatures &= ~(1 << 6)

等价于:

mFeatures = mFeatures & ~64

此时,~64为:

~1000000

执行"~"操作后,等价于:

0111111

本身我们将二进制的第7位,设置位1,就代表了此时设置了FEATURE_CONTEXT_MENU,如果我们执行"~"操作,也就将该位置为0,也就等于清除了该设置。

随后在对mFeatures进行设置:

mFeatures & ~64

等价于如下的二进制执行"&"操作:

1001010
0111111

结果为:

mFeatures = 10// 二进制1010

由于对FEATURE_CONTEXT_MENU设置进行"~“操作,保证了对应的设置位为0,不管之前的这个位置是0还是1,进行”&“操作,结果都为0,保证了清除该设置位。然后其他位全部位1,进行”&"操作后,其他位是什么还是什么,所以,就保证了其他设置位不变,清除了相应的设置。


总结

  • 添加一个变量设置,使用"或"("|")符号

    mFeatures |= flag
    
  • 判断是否包含某个变量设置,使用"与"("&")符号,判断结果是否等于0。

    (mFeatures & flag) != 0
    

    判断是否包含多个变量中的一个或者多个

    (mFeatures & (flag1 | flag2 | flag3)) != 0
    
  • 清除某个变量设置,使用"与 非"("& ~")

    mFeatures & ~flag
    
  • Java中将int值转换为二进制的输出,执行如下代码:

    System.out.println(Integer.toBinaryString(100));
    

你可能感兴趣的:(基础篇)