You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ZoomageView上设置点击监听器并保留缩放功能

实现ZoomageView缩放与点击显示/隐藏底部导航栏的兼容方案

问题场景

用Kotlin开发Android图库应用,使用ZoomageView全屏展示图片,需求是点击图片时切换底部导航栏(含分享、收藏功能)的显示/隐藏,但遇到冲突:

  • 给Holder.itemView设置点击事件:图片可正常缩放,但底部导航栏无响应
  • 给sliderImageView(ZoomageView)设置点击事件:底部导航栏可切换显示/隐藏,但图片无法缩放

布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.jsibbold.zoomage.ZoomageView
        android:id="@+id/sliderImageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:zoomage_animateOnReset="true"
        app:zoomage_autoCenter="true"
        app:zoomage_autoResetMode="UNDER"
        app:zoomage_maxScale="8"
        app:zoomage_minScale="0.6"
        app:zoomage_restrictBounds="false"
        app:zoomage_translatable="true"
        app:zoomage_zoomable="true"
        />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:visibility="gone"
        app:menu="@menu/bottom_navigation_menu" />

</LinearLayout>

Adapter原代码:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val photoPath: Uri = allImageList[position]
    val slideImageView: ImageView = holder.itemView.findViewById(R.id.sliderImageView)
    Glide.with(context).load(photoPath).into(slideImageView)

    var bottomNavigationView: BottomNavigationView =
        holder.itemView.findViewById(R.id.bottomNavigationView)

    // 允许缩放但不显示底部菜单
    holder.itemView.setOnClickListener {
        bottomNavigationView.visibility =
            if (bottomNavigationView.visibility == View.VISIBLE) View.GONE else View.VISIBLE
    }

    // 显示底部菜单但无法缩放
    slideImageView.setOnClickListener {
        bottomNavigationView.visibility =
            if (bottomNavigationView.visibility == View.VISIBLE) View.GONE else View.VISIBLE
    }

}

解决思路

ZoomageView本身会处理缩放、平移的触摸事件,直接给它设置OnClickListener会覆盖其内部的手势处理,导致无法缩放;而给父布局itemView设置点击时,ZoomageView会消费触摸事件,导致父布局的点击事件无法触发。

正确做法是给ZoomageView添加触摸监听,通过判断触摸时长和移动距离识别单次点击,再触发底部导航栏的显示/隐藏,同时保留ZoomageView的原生缩放功能。

修改后的Adapter代码

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val photoPath: Uri = allImageList[position]
    val slideImageView = holder.itemView.findViewById<com.jsibbold.zoomage.ZoomageView>(R.id.sliderImageView)
    Glide.with(context).load(photoPath).into(slideImageView)

    val bottomNavigationView = holder.itemView.findViewById<BottomNavigationView>(R.id.bottomNavigationView)

    // 用GestureDetector识别点击事件,不干扰ZoomageView的缩放
    val gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
            // 切换底部导航栏显示状态
            bottomNavigationView.visibility = if (bottomNavigationView.visibility == View.VISIBLE) View.GONE else View.VISIBLE
            return true
        }
    })

    // 给ZoomageView设置触摸监听,传递事件给GestureDetector
    slideImageView.setOnTouchListener { _, event ->
        gestureDetector.onTouchEvent(event)
        // 返回false,让ZoomageView继续处理缩放等手势
        false
    }
}

代码说明

  1. 使用GestureDetectorCompat的onSingleTapConfirmed方法识别可靠的单次点击,避免和缩放手势混淆
  2. 给ZoomageView设置OnTouchListener,将触摸事件传递给GestureDetector后返回false,让ZoomageView继续处理自身的缩放、平移逻辑
  3. 移除原有的itemView和slideImageView的OnClickListener,避免事件冲突

内容的提问来源于stack exchange,提问作者Iamvp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 08:26:33