简体   繁体   English

如何使用内部带有ImageView的ViewPager OnTouchListener以及OnClickListener

[英]How to use ViewPager OnTouchListener with ImageView inside it which also has OnClickListener

I have a ViewPager that have 4 pages, the pages will keep sliding using runable and handler....each page contains an ImageView, the ImageView onClickListener event is set in the Adapter 我有一个包含4页的ViewPager,这些页面将使用可运行和处理程序保持滑动。...每个页面都包含一个ImageView,在Adapter中设置了ImageView onClickListener事件

the ViewPager has OnTouchListener event set while initialization ViewPager在初始化时设置了OnTouchListener事件

I'm setting the ViewPager OnTouchListener event to stop sliding when the user touches the viewpager and continue sliding when user release his finger 我将ViewPager OnTouchListener事件设置为在用户触摸Viewpager时停止滑动,并在用户松开手指时继续滑动

here is how i set ViewPager OnTouchListener event: 这是我设置ViewPager OnTouchListener事件的方法:

    BandsViewPager.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    stopSliding = true;
                    bandsHandler.removeCallbacks(animateBandsViewPager);
                    break;

                case MotionEvent.ACTION_CANCEL:
                    break;

                case MotionEvent.ACTION_UP:
                    // calls when touch release on ViewPager
                    if (bands != null && bands.size() != 0) {
                        stopSliding = false;
                        bandsRunnable(bands.size());
                        bandsHandler.postDelayed(animateBandsViewPager, ANIM_VIEWPAGER_DELAY);
                    }

                    break;

                case MotionEvent.ACTION_MOVE:
                    // calls when ViewPager touch
                    if (bandsHandler != null && stopSliding == false) {
                        stopSliding = true;
                    }
                    break;
            }
            return false;
        }
    });

and Here is how I set ImageView OnClickListener inside the ViewPager adapter class: 这是我在ViewPager适配器类中设置ImageView OnClickListener的方法:

    mImageView.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            switch(ClickActionType){
                case BAND_CLICK_ACTION_BRAND:
                    Categories_Fragment categoriesFrag= new Categories_Fragment();
                    Bundle categoriesArgs = new Bundle();
                    categoriesArgs.putInt("BrandId", ClickActionTypeId);
                    categoriesArgs.putInt("TabId", TabId);
                    if (UI.getAppLanguage() == 0)
                        categoriesArgs.putString("BrandName", TitleAr);
                    else
                        categoriesArgs.putString("BrandName", TitleEn);
                    categoriesFrag.setArguments(categoriesArgs);
                    FManager.beginTransaction()
                            .replace(R.id.main_content, categoriesFrag, Categories_Fragment.ARG_ITEM_ID)
                            .addToBackStack(Categories_Fragment.ARG_ITEM_ID)
                            .commit();
                    break;

                case BAND_CLICK_ACTION_ITEM:
                    Item_Details_Fragment itemDetailsFrag= new Item_Details_Fragment();
                    Bundle itemDetailsArgs = new Bundle();
                    itemDetailsArgs.putInt("ItemId", ClickActionTypeId);
                    itemDetailsFrag.setArguments(itemDetailsArgs);
                    FManager.beginTransaction()
                            .replace(R.id.main_content, itemDetailsFrag, Item_Details_Fragment.ARG_ITEM_ID)
                            .addToBackStack(Item_Details_Fragment.ARG_ITEM_ID)
                            .commit();
                    break;
                case BAND_CLICK_ACTION_CATEGORY:
                    Items_Fragment itemsFrag= new Items_Fragment();
                    Bundle itemsArgs = new Bundle();
                    itemsArgs.putInt("CategoryId", ClickActionTypeId);
                    if (UI.getAppLanguage() == 0)
                        itemsArgs.putString("CategoryName", TitleAr);
                    else
                        itemsArgs.putString("CategoryName", TitleEn);
                    itemsArgs.putInt("BrandId", 0);
                    itemsArgs.putInt("TabId", TabId);
                    itemsFrag.setArguments(itemsArgs);
                    FManager.beginTransaction()
                            .replace(R.id.main_content, itemsFrag, Items_Fragment.ARG_ITEM_ID)
                            .addToBackStack(Items_Fragment.ARG_ITEM_ID)
                            .commit();
                    break;
                default:
            }

        }
    });

If I remove the ImageView OnClickListener then the ViewPager will receive touch events. 如果删除ImageView OnClickListener,则ViewPager将接收触摸事件。

The reason your ImageView is stealing the MotionEvent callbacks from your ViewPager is because the OnTouchListener.onTouch() method of your ViewPager always returns false . 你的理由ImageView被窃取MotionEvent从您的回调ViewPager是因为OnTouchListener.onTouch()你的方法ViewPager总是返回false This means it will not capture any new MotionEvent callbacks after another View (your ImageView ) returns true in the onTouchEvent() method. 这意味着在另一个View (您的ImageView )在onTouchEvent()方法中返回true后,它将不捕获任何新的MotionEvent回调。 Any View that is "clickable" returns true for any MotionEvent , and setting an OnClickListener for a View makes it clickable. 任何View是“点击”返回true为任何MotionEvent ,并设置一个OnClickListenerView使得点击。

Now the immediate reaction might be to make the OnTouchListener.onTouch() method return true for some or all case statements. 现在,立即的反应可能是使OnTouchListener.onTouch()方法对某些或所有case语句返回true But this would either make the ViewPager intercept all MotionEvent callbacks, or not give you the functionality that you want. 但是,这要么使ViewPager拦截所有 MotionEvent回调,还是不给你你想要的功能。

The correct implementation would be to subclass ViewPager and override the onInterceptTouchEvent and onTouchEvent methods. 正确的实现将是ViewPager子类,并重写onInterceptTouchEventonTouchEvent方法。 The key is not to return true in the case of MotionEvent.ACTION_DOWN in onTouchEvent , as this will delegate every gesture to the ViewPager . 关键是不回true在的情况下MotionEvent.ACTION_DOWNonTouchEvent ,因为这将委派的每一个手势给ViewPager Instead you should intercept the MotionEvent callbacks in the case of MotionEvent.ACTION_MOVE after a "slop" threshold has been exceeded. 相反,你应该拦截 MotionEvent中的情况下,回调MotionEvent.ACTION_MOVE一后“污”已经超过阈值。 This will send all successive MotionEvent callbacks to the ViewPager.onTouchEvent() method, instead of any child views. 这将发送所有连续MotionEvent回调到ViewPager.onTouchEvent()方法,而不是任何一个孩子的意见。

The Android documentation includes best practices on managing touch events . Android文档包含有关管理触摸事件的最佳实践。 I also highly recommend watching Mastering the Android Touch System if you want to have a better understanding of how the Android framework handles touch events. 如果您想更好地了解Android框架如何处理触摸事件,我也强烈建议观看Mastering the Android Touch System

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM