前言
最近这段时间在忙着开发一个Android游戏,当然并不是真正的游戏,只是一个伪游戏而已,因为应用需要的图片资源和布局都比较多,所以难免就出现了下面这种类型的代码片段:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20switch (index) {
case 1:
mView = mInflater.inflate(R.layout.layout_gift_one, null);
break;
case 2:
mView = mInflater.inflate(R.layout.layout_gift_two, null);
break;
case 3:
mView = mInflater.inflate(R.layout.layout_gift_three, null);
break;
case 4:
mView = mInflater.inflate(R.layout.layout_gift_four, null);
break;
case 5:
mView = mInflater.inflate(R.layout.layout_gift_five, null);
break;
case 6:
mView = mInflater.inflate(R.layout.layout_gift_six, null);
break;
}
对于我这种有代码洁癖的人,每次看到这种代码我心里着实是不舒服的,今天上午写代码的时候,遇到一个这样的需求,简化一下大致是这样的:
需求
有6个textview用于显示6种商品的数量,然后定义了一个长度为6的数组用于存放6种商品的数量,那么有一个需求是要在特定的条件下将6种商品的数量置为0,同时在textview显示
分析
遇到这种问题,数组置0很简单,但是问题来了:6个textview都是从布局文件中获取的,每个textview的资源id不一样,每个textview的名字都不一样,相当于要执行6次findviewById
和xxxTextView.setText("0")
,我一想到这里,感觉如果这样写简直太丑陋了
心想既然标识商品的数量用的就是一个数组,那么可以不可以把6个textview也放到数组里面?正好这两天在stackoverflow上看另一个问题的时候,好像看到过类似的用法,模糊中记得好像是用的getIdentifier,于是就搜索了一下,果然可以,成功的将6个textview用一行代码就放到了一个长度为6的数组中,不用6次findViewById,也不用6次xxTextView.setText(“0”)了,一个循环就搞定了
实现
学习要举一反三,学以致用,那么当我再次看到项目中开头那段代码的时候,心里想这个不是也可以使用getIdentifier简化吗,于是简化之后上面的代码就变成这样了。1
2
3int layoutId = getResources().getIdentifier(
"layout_gift_" + index, "layout", getPackageName());
mView = mLayoutInflater.inflate(layoutId, null);
是不是看起来整洁了很多
扩展
然后又点进去getIdentifier方法的源码里面看了一下,用法简介是这样写的:
1 | /** |
也就是说传递参数的方式有两种情况:
第一个参数按照
package:type/entry
的方式传递的话,那么后面两个type和package参数是可选的,也就是可以传null,就像这样:1
2int layoutId = getResources().getIdentifier(
"com.huhulab.xxx:layout/layout_1",null,null);第一个参数的格式也就是:包名+”:”+资源属性类型+”/“+资源名,其中资源属性类型就是指你要获取的资源是layout,id或者drawable之类的
就是按照我上面的那种方法传递,像这样:
1
2int textId = getResources().getIdentifier(
"text1",id,"com.huhulab.xxx");三个参数分别是:资源名,资源属性类型,包名
注意
源码简介里面还有这么一句提示:1
2Note: use of this function is discouraged. It is much more
efficient to retrieve resources by identifier than by name.
也就是说并不鼓励使用这个方法,因为通过id获取资源比通过名字获取资源更高效,也就是说这种方法耗时可能会比较久,所以除非必须不要过多使用这个方法
当然因为R.layout和R.id等其实都是一个内部类,你也可以通过反射获取类中的某一个变量,也就是你要找的那个资源名