在看系统源码和开源源码时,总是能看到关于attr的使用,一遇到就烦躁,不清楚是什么个意思,为此决定啃掉这块内容,说不定掌握之后,能提高自己的开发效率。今天准备初步的学习总结一下。
首先学习一些基本知识,请参考下面两篇博文,attr在自定义样式的用法:
http://googlers.iteye.com/blog/1122585
http://www.cnblogs.com/angeldevil/p/3479431.html
But,我在看android4.4系统settings wifi方面的源码时,发现了attr的另一种用法,目前还不是系统了解,先记录一下。
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/signal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="?attr/wifi_signal"
android:contentDescription="@null" />
看android:src="?attr/wifi_signal",这是一种新的用法,调用的是wifi_signal属性,那么wifi_signal是在哪儿定义的呢?
<resources>
<attr name="ic_menu_add" format="reference" />
<attr name="ic_menu_moreoverflow" format="reference" />
<attr name="ic_wps" format="reference" />
<attr name="setup_divider_color" format="reference" />
<attr name="wifi_signal" format="reference" />
<style name="SetupWizardWifiTheme" parent="android:Theme.Holo.NoActionBar">
<item name="android:windowSoftInputMode">adjustPan</item>
<item name="android:alertDialogTheme">@style/Theme.WifiDialog</item>
<item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_holo_dark</item>
<item name="setup_divider_color">@color/setup_divider_color_dark</item>
<item name="wifi_signal">@drawable/wifi_signal_dark</item>
</style>
上面是wifi_signal的定义,然后在theme的style中给其赋值,android:src="?attr/wifi_signal"相当于是使用这个属性。
这个attr使用方法就讲完了,但是,还遇到一种attr的使用。
下面是wifi_signal_dark的文件
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.sailang.wifisetting">
<item settings:state_encrypted="false" android:drawable="@drawable/wifi_signal_open_dark" />
<item settings:state_encrypted="true" android:drawable="@drawable/wifi_signal_lock_dark" />
</selector>
根据上面的第二篇博文,我们知道settings:state_encrypted = "false"是给state_encrypted属性赋值,如果是在View中这样使用,但是,在item这里使用就不是这个意思了,我们知道selector是个选择器,state_encrypted如果为false是第一个item,如果为true是true是第二个item。
那问题来了,是在哪里决定state_encrypted为false还是true?以WifiSettings为例。
@Override
protected void onBindView(View view) {
super.onBindView(view);
ImageView signal = (ImageView) view.findViewById(R.id.signal);
if (mRssi == Integer.MAX_VALUE) {
signal.setImageDrawable(null);
} else {
//根据信号强弱选择对应的图标
signal.setImageLevel(getLevel());
//这种设置和在XML中android:src="?attr/wifi_signal"设置是等价的
signal.setImageDrawable(getContext().getTheme().obtainStyledAttributes(new int[] {R.attr.wifi_signal}).getDrawable(0));
signal.setImageState((security != SECURITY_NONE) ? STATE_SECURED : STATE_NONE, true);
}
}
private static final int[] STATE_SECURED = {
R.attr.state_encrypted
};
private static final int[] STATE_NONE = {};
是setImageState这个决定的。
可能有一些地方理解的不对,请留言交流,以后还会不断更新的。