androidkotlinimageviewandroid-gallery

How to set onClick Listener on ZoomageView


I am Making gallery app for android in kotlin.I am using ZoomageView for displaying image in fullScreen.I also want to show Menu and bottom for share,add/remove Favorite etc on singel tap of imag click but there is problem with it. If i set setOnClickListener on Holder.Holder.itemView it allow me to zoom in and out but it won't show me menu. and if i set setOnClickListener on sliderImageView(ZoomageView) it will show menu bur i can no longer zoom in or out the image.

<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>
 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)

        // It allow me to zoom in and out but won't show me Bottom Menu
        holder.itemView.setOnClickListener {
            bottomNavigationView.visibility =
                if (bottomNavigationView.visibility == View.VISIBLE) View.GONE else View.VISIBLE
        }

        // It show Bottom menu but i can no longer zoom in or out 
        slideImageView.setOnClickListener {
            bottomNavigationView.visibility =
                if (bottomNavigationView.visibility == View.VISIBLE) View.GONE else View.VISIBLE
        }

    }

I want both zoom in and out image and also show and hide menu on sigle tap/click of image.


Solution

  • I checked the source code of com.jsibbold.zoomage.ZoomageView, and I think the reason why the ZoomageView can not perform both tap and zoom at the same time is this line:

        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            // if the view is clickable, then it will skip handling zoom gestures
            if (!isClickable() && isEnabled() && (zoomable || translatable)) {
                // Handle the zoom gestures
                ......
            }
    
            return super.onTouchEvent(event);
        }
    

    You can see if the view is Clickable, then it will skip handling zoom gestures.

    So, the solution will be:

    Here is the solution code, it seems work perfectly for my test:

    // First define a GestureTap class, just call performClick() when a tap gesture is detected
    public class GestureTap extends GestureDetector.SimpleOnGestureListener {
        View view;
        public GestureTap(View view) {
            super();
            this.view = view;
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            view.performClick();
            return true;
        }
    }
    
    // set OnClickListener as you want
    slideImageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Log.e("wangpeiming", "imageView clicked");
            bottomNavigationView.visibility =
                    if (bottomNavigationView.visibility == View.VISIBLE) View.GONE else View.VISIBLE
        }
    });
    
    // set the view to not clickable, so that it can handle zoom gestures afterward.
    slideImageView.setClickable(false);
    
    // use OnTouchListener and gestureDetector to detect tap gesture
    final GestureDetector gestureDetector = new GestureDetector(getApplicationContext(), new GestureTap(slideImageView));
    slideImageView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // let the gestureDetector to check and handle if there is a tap gesture
            gestureDetector.onTouchEvent(event);
            // must return false so that the view's onTouchEvent() can receive the event and handle zoom gestures.
            return false;
        }
    });
    

    Hope it helps~