Android通过getResources().getIdentifier()获取Drawable设置按钮背景的正确方案
问题根因
getResources().getIdentifier()方法的返回值始终是int类型的资源索引值,不会根据传入的资源类型直接返回对应类型的对象。
- 之前写的string资源逻辑能正常运行,是因为
setVoc()方法本身支持接收字符串资源的int类型ID,和返回值类型完全匹配 - 调用
setBackground()时,方法要求传入的参数是Drawable类型,直接把int类型的资源ID传入就会触发类型不匹配的编译报错
另外现有代码还存在数组越界的隐藏运行时bug:初始化的button数组是0起始下标,下标0存button1,一直到下标9存button10,但循环从i=1开始、条件设为i<11,会直接跳过下标0的button1,当i=10时还会访问到数组范围外的位置,运行时直接崩溃。
修正实现
核心调整点
- 对齐数组下标的遍历范围,避免越界、漏控件
- 把拿到的drawable资源intID,通过兼容方法转换为Drawable对象后再设置
- 增加资源ID有效性判断,避免拼接资源名错误时拿到无效ID触发空指针
修正后代码
Button[] button = new Button[] {button1, button2, button3, button4, button5, button6, button7, button8, button9, button10}; // 从0开始遍历数组有效范围 for (int i = 0; i < button.length; i++) { // 按照原有命名规则拼接drawable资源名:gr1、gr2...gr10 int drawableResId = getResources().getIdentifier("gr" + (i + 1), "drawable", getPackageName()); // 资源ID有效时再执行设置逻辑 if (drawableResId != 0) { // 用兼容API获取Drawable对象,避免高版本主题样式失效 button[i].setBackground(ContextCompat.getDrawable(this, drawableResId)); } }
补充说明:如果使用已经废弃的单参数
getResources().getDrawable(int)方法,在Android 6.0以上系统会出现drawable主题样式不匹配的问题,推荐始终用ContextCompat.getDrawable()做版本兼容。
内容的提问来源于stack exchange,提问作者cheese steak jimmy's
相关产品推荐
相关产品推荐

