参考自:感谢大佬们的帮助
https://droidyue.com/blog/2014/09/12/get-resource-id-by-name-in-android/
https://blog.csdn.net/mingli198611/article/details/7105850
一.XML文件中@,@+,?,@*的含义以及区别
1.@
- 类型一:(引用自定义资源)
形如:android:xx = "@[package:]type/name",自定义package:省略
例如:
android:text="@string/app_name"
android:textColor="@color/gary"
- 类型二:(引用系统资源)
形如:android:xx = "@android:type/name",为@[package:]type/name的一个子类
例如:
android:textColor="@android:color/white"
2.@* 引用系统所有资源
形如:android:xx = "@*android:type/name"
注意:android:xx = "@android:type/name"只能调用系统的public属性资源
3.? 引用主题属性-无需具体值,会在主题属性中查找并替换
只能在XML文件或style资源中使用。
形如:?[namespace:]type/name,这里类型可选。
例如:android:textColor="?attr/colorAccent"
4.@引用资源 @+创建资源 形如:@+type/name
- 代表在R文件中新添加一个静态final常量值
--@+id/name 代表创建一个名为name的资源标识引用
--@id/name 引用名为name的资源标识引用(如果资源存在)
--@android:id/name 引用系统name资源
例如:
android:id="@+id/tv_test" 代表创建一个tv_test的资源标识引用
android:id="@id/tv_test" 引用一个名为tv_test的资源
二.引用/获取资源文件的值
1.传统且常见的使用方式(根据资源ID获取资源值)
通过getResource.getXXX()获取值。
例如:
resources = getResources();
packageName = getPackageName();
Log.e(TAG, "packageName:" + packageName);
//常用-正常获取资源
//通过资源ID获取字符串
String str = resources.getString(R.string.app_name);
//通过资源ID获取颜色值
int colorBlue = resources.getColor(R.color.blue);
Log.e(TAG, "colorBlue:" + colorBlue);
String []array = resources.getStringArray(R.array.str_array);
Log.e(TAG, "array:" + array.length);
Drawable drawable = resources.getDrawable(R.drawable.point_bg_checked);
2.特殊情况(通过资源名获取资源ID,在通过资源ID设置相对应的值)
//通过getIdentifier(name,type,package)
偶尔我们通过网络请求获取到资源名称,然后设置相应的资源值;这时候就使用第二种方式。
例如:
int icLauncherId = resources.getIdentifier("ic_launcher_background", "drawable", packageName);
//name完整
int anotherIcLauncherId = resources.getIdentifier(packageName+":drawable/ic_launcher_background", null, null);
Log.e(TAG, "icLauncherId:" + icLauncherId);
Log.e(TAG, "anotherIcLauncherId:" + anotherIcLauncherId);
int colorId = resources.getIdentifier("colorAccent", "color", packageName);
Log.e(TAG, "colorId:" + colorId);
查看源码:
/**
* Return a resource identifier for the given resource name. A fully
* qualified resource name is of the form "package:type/entry". The first
* two components (package and type) are optional if defType and
* defPackage, respectively, are specified here.
*
* <p>Note: use of this function is discouraged. It is much more
* efficient to retrieve resources by identifier than by name.
*
* @param name The name of the desired resource.
* @param defType Optional default resource type to find, if "type/" is
* not included in the name. Can be null to require an
* explicit type.
* @param defPackage Optional default package to find, if "package:" is
* not included in the name. Can be null to require an
* explicit package.
*
* @return int The associated resource identifier. Returns 0 if no such
* resource was found. (0 is not a valid resource ID.)
*/
public int getIdentifier(String name, String defType, String defPackage) {
return mResourcesImpl.getIdentifier(name, defType, defPackage);
}
它的三个参数name,defType,defPackage
分别对应了本文中第一部分的内容。
参数 | xml文件 |
---|---|
name | name |
defType | type |
defPackage | package |
即@[package:]type/name
.
注意:
- 获取资源ID为0时,说明不存在。
- 此方法并不高效。
- 见案例;当name完整时,后面两个参数直接填null即可。