Android Studio中Button加载本地Drawable图片失败问题排查
问题分析与解决
你遇到的核心问题是导入了系统自带的android.R类,而非你项目自身生成的R类,这直接导致代码无法识别你放在res/drawable里的自定义图片资源。下面一步步拆解问题并修正代码:
1. 最关键的错误:R类导入错误
你代码第一行导入的import android.R是Android系统提供的资源类,仅包含系统自带的资源(比如默认图标、系统样式),完全不会包含你自己添加的notebook.png和desktop_pc.png。
解决方法:
- 删除
import android.R这一行 - 替换为你项目的
R类导入:import com.example.myproject.R(和你的包名保持一致)
2. 其他需要修正的代码问题
除了R类的问题,你的代码还有几个小问题会导致运行报错,一并调整:
- 构造函数写法错误:
data class MyButton() : androidx.appcompat.widget.AppCompatButton(context)未接收Context参数,且data class不适合定义View子类(data class多用于数据承载,View是UI组件) - CountDownTimer内的
this指向错误:this.setBackgroundResource里的this指向CountDownTimer对象,而非MyButton实例,会引发编译错误 exitProcess的不合理性:直接调用exitProcess(-1)会强制杀死进程,这不是优雅的做法,建议替换为重启定时器或其他业务逻辑- 随机数范围优化:
(0..20).random()的概率不对等,换成(0..1).random()可实现50%的切换概率
修正后的完整代码
package com.example.myproject import android.content.Context import android.util.Log import android.os.CountDownTimer import androidx.appcompat.widget.AppCompatButton // 不要用data class定义View子类,直接继承AppCompatButton即可 class MyButton(context: Context) : AppCompatButton(context) { // 自定义定时器时长,这里以10秒为例 private val timerDuration = 10000L init { this.text = "test" this.setOnClickListener { v -> Log.d("CLICK", "Button clicked!") } object : CountDownTimer(timerDuration, 1000) { override fun onTick(millisUntilFinished: Long) { // 生成0或1的随机数,实现50%概率切换图片 val rnd = (0..1).random() if (rnd == 0) { // 使用项目自身的R类,即可访问自定义drawable资源 this@MyButton.setBackgroundResource(R.drawable.notebook) } else { this@MyButton.setBackgroundResource(R.drawable.desktop_pc) } } override fun onFinish() { // 替换为重启定时器(示例),而非强制杀死进程 this.start() // 若确实需要退出,需导入java.lang.System.exitProcess // System.exitProcess(0) } }.start() } }
最后验证步骤
- 确认
notebook.png和desktop_pc.png放在res/drawable根目录下(避免放在drawable-v24这类版本专属目录,除非有特殊适配需求) - 点击Android Studio的
Build -> Clean Project,再执行Build -> Rebuild Project,确保R类重新生成 - 运行项目,此时应该能正常切换图片了
内容的提问来源于stack exchange,提问作者enneenne
相关产品推荐
相关产品推荐

