`

Android开发ScrollView上下左右滑动事件冲突整理一(根据事件)

 
阅读更多

主要通过重写 onInterceptTouchEvent 事件来解决,代码如下:

package com.cm.android.pad.view.itemView;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.ScrollView;
import android.widget.Scroller;

public class MultiScroll extends ScrollView {

    private static final int ANIMATION_SCREEN_SET_DURATION_MILLIS = 500;
    // What fraction (1/x) of the screen the user must swipe to indicate a page change
    private static final int FRACTION_OF_SCREEN_WIDTH_FOR_SWIPE = 4;
    private static final int INVALID_SCREEN = -1;
    /*
     * Velocity of a swipe (in density-independent pixels per second) to force a swipe to the
     * next/previous screen. Adjusted into mDensityAdjustedSnapVelocity on init.
     */
    private static final int SNAP_VELOCITY_DIP_PER_SECOND = 600;
    // Argument to getVelocity for units to give pixels per second (1 = pixels per millisecond).
    private static final int VELOCITY_UNIT_PIXELS_PER_SECOND = 1000;

    private static final int TOUCH_STATE_REST = 0;
    private static final int TOUCH_STATE_HORIZONTAL_SCROLLING = 1;
    private static final int TOUCH_STATE_VERTICAL_SCROLLING = -1;
    private int mCurrentScreen;
    private int mDensityAdjustedSnapVelocity;
    private boolean mFirstLayout = true;
    private float mLastMotionX;
    private float mLastMotionY;
    //private OnScreenSwitchListener mOnScreenSwitchListener;
    private int mMaximumVelocity;
    private int mNextScreen = INVALID_SCREEN;
    private Scroller mScroller;
    private int mTouchSlop;
    private int mTouchState = TOUCH_STATE_REST;
    private VelocityTracker mVelocityTracker;
    private int mLastSeenLayoutWidth = -1;
    
	public MultiScroll(Context context) {
		super(context);
		init();
	}

	public MultiScroll(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public MultiScroll(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
    private void init() {
        mScroller = new Scroller(getContext());

        // Calculate the density-dependent snap velocity in pixels
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
                .getMetrics(displayMetrics);
        mDensityAdjustedSnapVelocity =
                (int) (displayMetrics.density * SNAP_VELOCITY_DIP_PER_SECOND);

        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
        mTouchSlop = configuration.getScaledTouchSlop();
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
    }
    

    @Override
    public boolean onInterceptTouchEvent(final MotionEvent ev) {
        /*
         * By Yoni Samlan: Modified onInterceptTouchEvent based on standard ScrollView's
         * onIntercept. The logic is designed to support a nested vertically scrolling view inside
         * this one; once a scroll registers for X-wise scrolling, handle it in this view and don't
         * let the children, but once a scroll registers for y-wise scrolling, let the children
         * handle it exclusively.
         */
        final int action = ev.getAction();
        boolean intercept = false;

        switch (action) {
            case MotionEvent.ACTION_MOVE:
             	
                /*
                 * If we're in a horizontal scroll event, take it (intercept further events). But if
                 * we're mid-vertical-scroll, don't even try; let the children deal with it. If we
                 * haven't found a scroll event yet, check for one.
                 */
                if (mTouchState == TOUCH_STATE_HORIZONTAL_SCROLLING) {
                	// Let children handle the events for the duration of the scroll event.
                    intercept = false;
                } else if (mTouchState == TOUCH_STATE_VERTICAL_SCROLLING) {
                	   /*
                     * We've already started a horizontal scroll; set intercept to true so we can
                     * take the remainder of all touch events in onTouchEvent.
                     */
                    intercept = true;
                } else { // We haven't picked up a scroll event yet; check for one.

                    /*
                     * If we detected a horizontal scroll event, start stealing touch events (mark
                     * as scrolling). Otherwise, see if we had a vertical scroll event -- if so, let
                     * the children handle it and don't look to intercept again until the motion is
                     * done.
                     */

                    final float x = ev.getX();
                    final int xDiff = (int) Math.abs(x - mLastMotionX);
                    boolean xMoved = xDiff > mTouchSlop;
                    
                    final float y = ev.getY();
                    final int yDiff = (int) Math.abs(y - mLastMotionY);
                    boolean yMoved = yDiff > mTouchSlop;

                    
                    if (xMoved) {
                        // Scroll if the user moved far enough along the X axis
                    	if(xDiff>=yDiff)
                        mTouchState = TOUCH_STATE_HORIZONTAL_SCROLLING;
                        mLastMotionX = x;
                    }

  

                    if (yMoved) {
                    	if(yDiff>xDiff)
                        mTouchState = TOUCH_STATE_VERTICAL_SCROLLING;
                        mLastMotionY = y;
                    }
                }

                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                // Release the drag.
                mTouchState = TOUCH_STATE_REST;
                intercept = false;
                break;
            case MotionEvent.ACTION_DOWN:
                /*
                 * No motion yet, but register the coordinates so we can check for intercept at the
                 * next MOVE event.
                 */
            	//Log.i("ViewPager-->", "Action_Down");
            	 mTouchState = TOUCH_STATE_REST;
                mLastMotionY = ev.getY();
                mLastMotionX = ev.getX();
                break;
            default:
                break;
            }

        Log.i("MultiScroll-->", intercept+"");
        return intercept;
    }
	
}
 
分享到:
评论
4 楼 honghe 2015-11-25  
文章写得可以啊,就是自定义了一个scrollview,放到布局文件中就可以再放入scrollview了,两个scrollview都可以滑动,思路还不错的
3 楼 qfyh05 2014-06-16  
return前需要调用super.onInterceptTouchEvent(ev);否则scrollview没有滚动效果。
2 楼 Neacy_Zz 2014-02-13  
zhq502502 写道
垃圾。写个博客毫无思路,看到就想骂,要么你就别对外开放。艹

真的不想说你是菜呢  还是没事找事。 看不懂就直说。
1 楼 zhq502502 2013-11-11  
垃圾。写个博客毫无思路,看到就想骂,要么你就别对外开放。艹

相关推荐

    Android ScrollView嵌套横向滑动控件时冲突问题

    前言:今天在开发的时候遇到这样的问题,最外层是ScrollView,里面嵌套了一个横向滑动的日历控件,在滑动日历的时候很卡顿。看到这种问题,自然而然的就会想到scrollview和其他可滑动控件的冲突问题。 解决思路 用户...

    Android中自定义ListView,解决scrollview嵌套listview 滑动事件冲突

    在Android开发中,ListView是用于显示大量数据列表的常用组件,而ScrollView则是一个可以垂直滚动的视图容器,常用于包含多个子视图。当在一个ScrollView内嵌套一个ListView时,由于两者都具有滑动功能,可能会导致...

    Android上下左右滑动支持同时滑动斜向任意方向滑动大图片浏览大图表浏览

    解决滑动冲突通常需要对Android的触摸事件处理机制有深入理解,包括如何处理MotionEvent的ACTION_DOWN、ACTION_MOVE和ACTION_UP等,以及如何在自定义View中正确处理这些事件。 总的来说,这个技术解决方案旨在提高...

    Android ScrollView+GridView左右滑动 自动定位滑动到某一项

    在Android开发中,ScrollView和GridView是两种常用的布局组件。ScrollView是一个可以包含单个子视图并允许用户滚动查看其内容的容器,而GridView则是一种可以显示多行多列数据的控件,通常用于创建网格视图。在这个...

    android完美解决listView与ScrollView滑动冲突

    总之,解决Android中的ListView与ScrollView滑动冲突问题,需要理解事件分发机制,以及掌握各种滚动控件的特性和API。通过合理的设计和编程,可以实现两者无缝协作,提供流畅的用户体验。在提供的压缩包文件...

    Android中自定义ScrollView的滑动监听事件

    通过以上步骤,我们可以成功地在Android中自定义一个带有滑动监听事件的ScrollView,这样就能在用户滑动时执行特定的业务逻辑,如加载更多数据、显示隐藏菜单等。自定义ScrollView是Android开发中的常见技巧,能帮助...

    ScrollView滑动事件冲突

    一个简单的demo,包含了onTouch,onLongClick,onClick调用日志,顺便解决ScrollView事件冲突,详情看博文:http://blog.csdn.net/msl0903/article/details/24205973

    ViewPager+Fragment左右滑动+上下滑动不冲突

    当ViewPager中的Fragment包含可滚动的内容(如ScrollView或ListView)时,可能会出现上下滑动与ViewPager的左右滑动冲突。为了解决这个问题,我们需要自定义一个ViewPager,覆盖其`onInterceptTouchEvent...

    ScrollView嵌套ListView滑动冲突的解决方法

    当需要在一个界面中同时展示大量数据和一些额外内容时,可能会将ListView嵌套在ScrollView中,但这种做法往往会导致滑动冲突的问题,即用户难以确定是想滚动整个ScrollView还是单独滑动ListView。本文将深入探讨这个...

    android ScrollView嵌套demo

    在Android开发中,ScrollView是一个非常常用的布局控件,它允许用户滚动查看屏幕无法完全显示的所有内容。当需要在布局中包含多个视图或者一个高度超过屏幕的视图时,我们通常会使用ScrollView。然而,当ScrollView...

    android滑动事件冲突解决

    在Android开发中,滑动事件处理是一个常见的挑战,尤其是在布局嵌套的情况下。"android滑动事件冲突解决"这个主题正是针对这种问题展开的。当两个可以竖直方向滑动的View(例如ScrollView、ListView或者...

    ScrollView与ListView的滑动冲突

    在Android开发过程中,我们经常会遇到ScrollView与ListView或GridView组合使用时出现的滑动冲突问题。这类问题通常表现为:当ScrollView内部包含一个ListView或GridView时,用户滑动屏幕时可能无法正常滚动列表中的...

    ScrollView嵌套ScrollView滑动

    在Android开发中,ScrollView是一种常用的布局控件,用于允许用户滚动查看超过屏幕大小的内容。当一个ScrollView内嵌套另一个ScrollView时,可能会遇到一些滑动事件处理的问题。这种情况下,我们需要理解Android事件...

    android 解决ScrollView和listView嵌套冲突问题(保证在ScrollView中滑动listView只响应listView的滑动)

    在Android开发中,ScrollView和ListView的嵌套是一个常见的需求,但同时也伴随着许多技术挑战,主要问题在于两者都具有滚动功能,导致冲突,使得用户在滚动时可能会遇到不确定的行为。本篇将详细介绍如何解决这种...

    android ListView和ScrollView事件冲突

    在Android开发中,ListView和ScrollView是两种常用的布局组件。ListView主要用于显示大量的数据列表,而ScrollView则用于实现可滚动的视图。然而,在实际应用中,当ListView被嵌套在ScrollView或者与ScrollView并存...

    解决scrollView和listview滚动冲突,实现listview滑动到顶端和底部之后还能拖拽一定的距离,松开后返回

    在Android开发中,ScrollView和ListView是两种常用的布局组件,它们分别用于实现可滚动的大视图和展示多行可滚动的数据列表。然而,在实际应用中,当这两种组件同时存在于一个界面时,滚动冲突的问题就会出现,导致...

    解决listview潜逃在scrollview中的滑动冲突

    在Android开发中,ListView和ScrollView都是非常常见的视图组件。ListView用于显示大量的数据列表,而ScrollView则可以包裹任意数量的子视图,实现整个布局的滚动。然而,当ListView被嵌套在ScrollView中时,就会...

    ScrollView+ListView 解决滑动冲突

    在Android开发中,ScrollView和ListView都是非常常见的视图组件。ScrollView是一个可以包含单个直接子视图并允许用户滚动查看其内容的布局。ListView则是一个显示大量数据并支持动态加载和用户交互的视图,通常用于...

Global site tag (gtag.js) - Google Analytics