财富坊cff888
  • 删除
  • 场景:ViewFlipper中添加了几个View,每个View中有几条itemView,每个itemView设置了setOnClickListener,ViewFlipper中通过GestureDetector来控制左右翻页效果。

    问题:不滑动,点击每个itemView,运行正常,当触发了滑动后,手势抬起时,依然会执行itemView的click事件

    解决:在继承的ViewFlipper中,拦截手势动作onInterceptTouchEvent来拦截MotionEvent.ACTION_UP动作,如果正在处理滑动,直接返回true,不再下发,放置触发itemView的点击事件,下面给出ViewFlipper的代码,里面有注释

    package com.custom.views.carousel;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;
    import android.widget.ViewFlipper;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by menghui on 2017/10/23.
     */
    
    public class JRJCarouselFlipper extends ViewFlipper {
        /**
         * 视图切换监听
         */
        public interface CarouselChanged{
            void onChanged(int oldIndex,int newIndex,View view);
        }
        private Animation rightInAnim,leftOutAnim,rightOutAnim,leftInAnim;
        private List<View> views;
        private CarouselChanged carouselChanged;
        //动画周期
        private int duration = 500;
        private GestureDetector gestureDetector;
        private GestureDetector.OnGestureListener gestureListener;
        //是否滑动中,该标志用来避免gesture的滑动和滑动View中item的点击冲突
        private boolean fling = false;
    
        public JRJCarouselFlipper(Context context) {
            super(context);
            init(context);
        }
    
        public JRJCarouselFlipper(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
    
        private void init(Context ctx){
            gestureListener = new GestureDetector.OnGestureListener() {
                @Override
                public boolean onDown(MotionEvent e) {
                    fling = false;
                    return false;
                }
    
                @Override
                public void onShowPress(MotionEvent e) {
    
                }
    
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return false;
                }
    
                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                    return false;
                }
    
                @Override
                public void onLongPress(MotionEvent e) {
    
                }
    
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                    fling = true;
                    if (e1.getX() - e2.getX() > 100) {
                        setInAnimation(rightInAnim);
                        setOutAnimation(leftOutAnim);
                        int old = getDisplayedChild();
                        showNext();
                        int newindex = getDisplayedChild();
                        triggerChanged(old,newindex);
                        return true;
                    } else if (e1.getX() - e2.getX() < -100) {
                        setInAnimation(leftInAnim);
                        setOutAnimation(rightOutAnim);
                            int old = getDisplayedChild();
                            showPrevious();
                            int newindex = getDisplayedChild();
                            triggerChanged(old,newindex);
                        return true;
                    }
                    return false;
                }
            };
            gestureDetector = new GestureDetector(gestureListener);
            views = new ArrayList<>();
            // 图片从右侧滑入
            rightInAnim = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 1.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f);
            rightInAnim.setDuration(duration);
    
            // 图片从左侧滑出
            leftOutAnim = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, -1.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f);
            leftOutAnim.setDuration(duration);
    
            // 图片从右侧滑出
            rightOutAnim = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, 1.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f);
            rightOutAnim.setDuration(duration);
    
            // 图片从左侧滑入
            leftInAnim = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, -1.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f,
                    Animation.RELATIVE_TO_PARENT, 0.0f);
            leftInAnim.setDuration(duration);
        }
    
        private void triggerChanged(int oldIndex,int newIndex){
            if (views.size() <= 0)
                return;
            if (carouselChanged != null){
                carouselChanged.onChanged(oldIndex,newIndex,views.get(newIndex));
            }
        }
    
        public CarouselChanged getCarouselChanged() {
            return carouselChanged;
        }
    
        public void setCarouselChanged(CarouselChanged carouselChanged) {
            this.carouselChanged = carouselChanged;
        }
    
        /**
         * 设置要轮播的视图列表
         * @param views
         */
        public void setViews(List<View> views) {
            this.views.clear();
            this.removeAllViews();
            this.views.addAll(views);
            for(View v:views){
                this.addView(v);
            }
        }
    
        /**
         * 拦截触屏,当按下时,fling=false,允许点击子视图中的item,当手势抬起时,为避免和滑动发生冲突,判断fling状态,
         * 如果处于滑动中,并且是手势抬起,返回true,不再向下传递,使item点击事件失效
         * @param ev
         * @return
         */
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_DOWN)
                fling = false;
            else if (fling && ev.getAction() == MotionEvent.ACTION_UP){
                return true;
            }
            return super.onInterceptTouchEvent(ev);
        }
    
        /**
         * 分发触屏,交给gesture
         * @param ev
         * @return
         */
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            gestureDetector.onTouchEvent(ev);
            return super.dispatchTouchEvent(ev);
        }
    
    }
    


    阅读全文
    版权声明:本文为博主原创文章,未经博主允许不得转载。

    Android循环滚动控件——ViewFlipper的使用

    假设现在让你实现一个垂直循环滚动的效果,你的第一反应是什么?如果是立马想找第三方或者想着自定义(嘿!真不嫌麻烦),那么你对ViewFlipper是陌生的,说明这篇博客对你是有价值的。请往下看: ? V...
    • u011150924
    • u011150924
    • 2017年03月08日 11:10
    • 2868

    viewpager与viewflipper详解以及横幅轮播页Banner

    ViewPager ViewPager的概念 在前面的博文《Android开发笔记(十九)底部标签栏TabBar》中,我们提到可以在一个主页面里通过选项卡方式,切换到不同的子页面。那么在手机上还有...
    • xiaoqiang_0719
    • xiaoqiang_0719
    • 2016年06月23日 17:33
    • 1131

    Android异常整理——《App研发录—架构设计,Crash分析和竞品技

    常见的异常 Java语法相关的异常 空指针:NullPointException 1.方法需要对传入的参数判空后再使用 2.对外部接口的调用,需要确保返回值中不为空 3.在App中过...
    • weijinqian0
    • weijinqian0
    • 2018年01月29日 12:51
    • 34

    android最全开发教程总结指南

    一、开发环境搭建 (已完成) 负责人:kris? 状态:已完成? 所整理标签为:搭建  SDK  JDK  NDK  Eclipse  ADT  模拟器  AVD  调试...
    • u013616976
    • u013616976
    • 2014年02月25日 19:10
    • 695

    ViewFlipper实现滚动布局

    今天在git上面看到了一个 仿淘宝头条的滚动效果,就看了下源码 ? ? ? ?然后自己照着写了下 ?然后顺便看了下 ViewFlipper 这个类 先上效果图吧: 自定义类继承?ViewFli...
    • XiFangzheng
    • XiFangzheng
    • 2016年11月28日 18:15
    • 909

    RecyclerView使用案例一之滑动冲突

    RecyclerView的使用在学习完ListView的使用后,我们可能会想,这么难用的控件到底是谁创造出来的,但是它却确确实实的陪伴我们度过了无数个岁月,并且屹立不倒,现在我们需要跟紧时代,去使用R...
    • Dota_wy
    • Dota_wy
    • 2017年08月21日 17:03
    • 425

    绝对转载

    数据库完整性 为了维护数据库完整性DBMS需要提供: 1. 提供定义完整性约束条件的机制 2. 提供完整性检查方法:一般在INSERT UPDATE DELETE语句执行后开始检查或者在事...
    • lc41214
    • lc41214
    • 2016年05月19日 20:06
    • 133

    Android性能优化系列之apk瘦身

    Android性能优化系列之apk瘦身 标签: ...
    • qq_36707431
    • qq_36707431
    • 2017年03月06日 11:46
    • 263

    解决自定义ListView中滑动事件和点击的setOnItemClickListener事件冲突的问题

    解决自定义ListView滑动事件和点击事件冲突的问题 一、问题描述 自定义的ListView加入下拉刷新和上拉加载更多后会出现滑动时触发了点击单个条目的setOnItemClickListene...
    • OONullPointerAlex
    • OONullPointerAlex
    • 2016年06月22日 10:41
    • 3063

    仿QQ侧滑删除,Listview上下滑动,Listview的iteam的点击事件等bug的解决

    网上ListView横向滑动删除Item这样的介绍也很多,但实用性不强,没有解决横向滑动和item的点击事件的冲突,废话少说,有图有真相,下面直接上代码 1:侧滑 2:侧滑的点击事件 ...
    • qq_29897079
    • qq_29897079
    • 2015年10月22日 15:57
    • 1896
    内容举报
    返回顶部
    收藏助手
    不良信息举报
    您举报文章:Android-ViewFlipper的滑动与子视图中item点击的冲突解决
    举报原因:
    原因补充:

    (最多只允许输入30个字)