一些不常見的場景敦锌,獲取到的資源是服務(wù)端下發(fā)字符串 "R.layout.sleep_activity","R.anim.fly_up"形式。
或者寫Demo的時候遣耍,一個Activity對應(yīng)多個布局,希望以外部傳入字符串形式設(shè)置 setContentView(layout)崖蜜。比如以下:
傳遞給目標(biāo)Activity一個字符串“R.layout.xxx”,而本地對應(yīng)的布局xxx有多個,需要加載到同一個目標(biāo)Activity
方法之一是通過反射烙肺,從R資源類獲取想要的“R.layout.xxx” 的int值纳猪,再setContentView(it)
/**
* 應(yīng)用:
* val layoutIdInt = Util.getIdByName(context, "layout", "R.layout.sleep_activity")
* */
fun getIdByName(context: Context, typeName: String, name: String): Int {
val packageName = context.packageName
var id = 0
try {
val r = Class.forName("$packageName.R")
val resTypes = r.classes
var dstClass: Class<*>? = null
// Search if has type we need?
for (i in resTypes.indices) {
// resTypes[i] is the type of resource, eg. "com.jesen.cod.layoutadvanced.R$anim"
// end is typeName, eg. "anim"
val end = resTypes[i].name.split("\\$").toTypedArray()[1]
if (end == typeName) {
dstClass = resTypes[i]
break
}
}
// Yes, find the type
if (dstClass != null) {
val simpleName = name.split("\\.").toTypedArray()[2]
val f = dstClass.getField(simpleName)
//f.setAccessible(true);
Log.d("XXX", "getIdByName, f : $f")
id = f.getInt(dstClass)
}
} catch (e: ClassNotFoundException) {
e.printStackTrace()
} catch (e: IllegalArgumentException) {
e.printStackTrace()
} catch (e: SecurityException) {
e.printStackTrace()
} catch (e: IllegalAccessException) {
e.printStackTrace()
} catch (e: NoSuchFieldException) {
e.printStackTrace()
}
return id
}