用kotlin写一个按钮的点击事件,让两张图片轮换

本文介绍了如何在Android应用中实现在点击按钮时切换ImageView中显示的图片,并通过反射获取ImageView的图片ID。利用Android Studio 4.1.3和Kotlin,创建布局文件并设置图片资源,通过监听按钮点击事件动态改变图片。同时,通过反射从AppCompatBackgroundHelper获取ImageView的背景图片ID,实现图片的交换效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

废话不说,直接上干货:

开发工具:Android Studio 4.1.3

开发语言:kotlin

重要的话写在前面: 要做两张或多张图片轮流交换,必须要得到图片的id号,而这个正在显示的图片的id号是不好直接得到的,

但可以使用getTag()得到。  以下程序就是通过这个“窍门” 弄出的结果 :)

第一步:准备两张图片jpg或png都可以,文件名为ab1.jpg和ab2.jpg

第二步:新建一个新的Android新工程,在编程环境下,将这两张图片拷贝粘贴到drawable资源目录下。

第三步:写布局:

<ImageView
    android:id="@+id/i1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ab1"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    />

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="换图片"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toBottomOf="@id/i1"/>

ImageView控件的目的就是为了显示图片,Button的目的就是为了让这两张图片进行轮换

第三步:在kotlin的程序

class MainActivity : AppCompatActivity(),View.OnClickListener{

    var btn1:Button?=null
    var i1:ImageView?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn1=findViewById<Button>(R.id.btn1)
        i1=findViewById<ImageView>(R.id.i1)
        btn1?.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when(v?.id){
            R.id.btn1 -> {
                if (i1?.getTag()==R.drawable.ab1){
                    i1?.setImageResource(R.drawable.ab2)
                    i1?.setTag(R.drawable.ab2)
                }else{
                    i1?.setImageResource(R.drawable.ab1)
                    i1?.setTag(R.drawable.ab1)
                }
            }
        }
    }
}

运行后,你点击换图片按钮,就可以在两幅图片之间进行交换了。

--------------------------------------------------------------------------------------------

还有一种做法就是用反射,使用反射的方法获取ImageView的id。

AppCompatImageView 这个是V7包的ImageView,可以看到有两个私有属性:有私有属性就可以用反射, 因为公有属性用反射是没有必要的。

private final AppCompatBackgroundHelper mBackgroundTintHelper;

private final AppCompatImageHelper mImageHelper;

再看两个属性对应的类源码,发现AppCompatImageHelper并没有私有属性,所以无法进行反射。

而AppCompatBackgroundHelper是有私有属性的,所以可以反射到mBackgroundResId ,所以这个就是我们要的id

    private int mBackgroundResId = -1;
    void onSetBackgroundResource(int resId) {
        this.mBackgroundResId = resId; //你看这里就可以得到你设置背景的图片id号,这也告诉我们,只要把前景图片设置为背景,就可以得到图片的id号了。
        this.setInternalBackgroundTint(this.mDrawableManager != null ? this.mDrawableManager.getTintList(this.mView.getContext(), resId) : null);
        this.applySupportBackgroundTint();
    }
因此,我们只能通过设置背景的方法获取图片id,不能使用setImageResource
为了获得图片id,我们做一个单例工具类:建一个工具包,在工具包中新建一个Utils单例类,类中再建一个

object Utils {
    fun getV7ImageResourceId(imageView: ImageView): Int {
        var imgid = 0
        val fields = imageView.javaClass.declaredFields
        for (f in fields) {
            if (f.name == "mBackgroundTintHelper") {
                f.isAccessible = true
                try {
                    val obj = f[imageView]
                    val fields2 = obj.javaClass.declaredFields
                    for (f2 in fields2) {
                        if (f2.name == "mBackgroundResId") {
                            f2.isAccessible = true
                            imgid = f2.getInt(obj)
                            Log.d("1111", "Image ResourceId:$imgid")
                        }
                    }
                } catch (e: IllegalAccessException) {
                    e.printStackTrace()
                }
            }
        }
        return imgid
    }
}

然后结合下面的语句就可以得使用了:

在Activity里设置背景图片

 ImageView imageView = findViewById(R.id.commit_img);
 imageView.setBackgroundResource(R.drawable.testimg);
 int imgid = Utils.getV7ImageResourceId(imageView);

完毕,完整代码如下:

class MainActivity : AppCompatActivity(), View.OnClickListener{

    var btn1: Button?=null
    var i1: ImageView?=null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn1=findViewById<Button>(R.id.btn1)
        i1=findViewById<ImageView>(R.id.i1)
        i1?.setBackgroundResource(R.drawable.ab1)
        btn1?.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        val imgid: Int = Utils.getV7ImageResourceId(i1!!)
        when(v?.id){
            R.id.btn1 -> {
                if(imgid==R.drawable.ab1){
                    i1?.setImageResource(R.drawable.ab2)
                    i1?.setBackgroundResource(R.drawable.ab2)
                }else{
                    i1?.setImageResource(R.drawable.ab1)
                    i1?.setBackgroundResource(R.drawable.ab1)
                }
            }
        }
    }
}

点击按钮时,就可以两个图片进行反复交换了。

 

<think>嗯,用户想用KotlinAndroid实现点击按钮切换图片的功能。首先,我需要回忆一下Android开发中处理按钮点击和图片切换的基本步骤。根据用户提供的引用,特别是引用[2]中的代码,虽然是用Java的,但可以转换成Kotlin。 首先,用户需要在XML布局文件中定义Button和ImageView。这部分可能用户已经完成,但需要确认是否正确设置ID,比如按钮android:id="@+id/myButton",图片视图的android:id="@+id/myImageView"。然后,用户需要在Kotlin代码中找到这些视图的引用,使用findViewById或者View Binding,但可能更推荐使用合成绑定或者View Binding来避免空指针。 接下来是处理点击事件。在Kotlin中,可以直接在Activity或Fragment中设置按钮的点击监听器,比如button.setOnClickListener { ... }。在监听器内部,需要切换图片的资源。用户提到要轮换两张图片,所以可能需要一个变量来记录当前显示的图片,比如一个布尔值isImage1,每次点击时切换这个变量,并根据状态设置对应的图片资源。 引用[2]中的代码使用了setBackgroundResource,但如果是设置图片内容,可能需要使用setImageResource方法。另外,用户提到Utils.getV7ImageResourceId,这可能与兼容性有关,但如果是标准的ImageView,直接使用setImageResource应该足够。 然后,用户需要准备两张图片资源,比如drawable下的img1和img2,确保它们已经正确添加到项目中。在代码中,通过R.drawable.img1和R.drawable.img2引用这些资源。 另外,引用[1]提到ShapeableImageView和圆角样式,如果用户需要图片有圆角效果,可能需要使用这个控件并设置相应的样式,但这可能属于额外的美化步骤,用户的问题主要是切换图片,所以可能不是必须的,但可以作为优化建议提及。 最后,测试代码是否正确,确保点击按钮图片能够切换。如果遇到问题,可能需要检查资源ID是否正确,视图是否正确绑定,以及点击事件是否被正确注册。 总结步骤应该是:布局定义视图,Kotlin中绑定视图,设置点击监听器,切换图片资源。同时,考虑可能的优化点,如使用View Binding、处理图片缩放类型,或者扩展更多图片的切换功能。</think>[逐步解答] 在 Android 中通过 Kotlin 实现按钮点击切换图片功能,可按以下步骤实现: 1. **布局文件设置** (XML部分) ```xml <Button android:id="@+id/btnSwitch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="切换图片"/> <ImageView android:id="@+id/ivTarget" android:layout_width="200dp" android:layout_height="200dp" android:scaleType="centerCrop"/> ``` *建议使用 ShapeableImageView 实现圆角效果时可参考引用[1]的样式设置* 2. **Kotlin 代码实现** (Activity/Fragment) ```kotlin // 声明初始状态 private var isFirstImage = true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.your_layout) val btnSwitch = findViewById<Button>(R.id.btnSwitch) val ivTarget = findViewById<ImageView>(R.id.ivTarget) // 设置初始图片 ivTarget.setImageResource(R.drawable.img1) btnSwitch.setOnClickListener { if (isFirstImage) { ivTarget.setImageResource(R.drawable.img2) } else { ivTarget.setImageResource(R.drawable.img1) } isFirstImage = !isFirstImage // 可添加 Toast 提示参考引用[3] } } ``` 3. **优化建议** - 使用 View Binding 替代 findViewById - 将图片资源存储在 drawable 目录 - 添加过渡动画提升体验 - 支持多图轮换时可改用数组存储资源ID [^1]: 引用[1]的圆角样式设置方法 [^2]: 引用[2]的图片切换核心逻辑参考 [^3]: 引用[3]的Toast提示扩展功能
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庭博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值