jfeinstein10 / SlidingMenu

An Android library that allows you to easily create applications with slide-in menus. You may use it in your Android apps provided that you cite this project and include the license in your app. Thanks!
Apache License 2.0
11.07k stars 5.03k forks source link

"addIgnoredView()" is useless #751

Open fuchaosz opened 8 years ago

fuchaosz commented 8 years ago

In English: I found the method "addIgnoredView()" is useless, when a view in ViewGroup. for example:

<LinearLayout
        android:id="@+id/ly_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </android.support.v4.view.ViewPager>

    </LinearLayout>

slidingMenu.addIgnoredView(viewpager); now it's useless and the viewpager can neither get the ACTION_DOWN,ACTION_MOVE,ACTION_UP nor "setOnPagerChangeListener()" , because of this(in CustomViewAbove.java):

private boolean isInIgnoredView(MotionEvent ev) {
        Rect rect = new Rect();
        for (View v : mIgnoredViews) {
            **v.getHitRect(rect);**
            if (rect.contains((int)ev.getX(), (int)ev.getY())) return true;
        }
        return false;
    }

v.getHitRect(rect). this method only get the location of v releated to it's parent, but the MotionEvent who's location is the whole screen,so rect.contains((int)ev.getX(), (int)ev.getY()) always return false, even if your touch point is in the ignored view. How to fix it? look at this:

    private boolean isInIgnoredView(MotionEvent ev) {
        Rect rect = new Rect();
        for (View v : mIgnoredViews) {
            //v.getHitRect(rect);
            //这里稍微做了修改,v.getHitRect只能获取相对于父控件的位置,如果v嵌套在一个viewGroup中,
            // 那么添加这个v到mIgnoredViews中将不会游任何效果,例如:LinearLayout嵌套一个ViewerPager,将ViewPager加入mIgnoredViews后,依然无法接受到滑动事件
            //所以这里改为v.getGlobalVisibleRect,获取v在整个屏幕的坐标,而MotionEvent的坐标也是相对于整个屏幕来测量的
            v.getGlobalVisibleRect(rect);
            if (rect.contains((int)ev.getX(), (int)ev.getY())) return true;
        }
        return false;
    }

use v.getGlobalVisibleRect(rect); inplace of `v.getHitRect(rect);

for more detail,please see my csdn blog: http://blog.csdn.net/fuchaosz/article/details/51513288

中文: 当一个子view嵌套在ViewGroup中,将这个子View加入SlidingMenu的ignoredViews中,即:slidingMenu.addIgnoredView(v),是不起作用的,例如:一个LinearLayout中包含一个ViewerPager,此时ViewPager的滑动事件会和SlidingMenu冲突,这时ViewPager将不能滑动,怎么办呢?可以调用slidingMenu.addIgnoredView(viewPager),然而这是无效的,原因在这里(在CustomViewAbove.java):

private boolean isInIgnoredView(MotionEvent ev) {
        Rect rect = new Rect();
        for (View v : mIgnoredViews) {
            **v.getHitRect(rect);**
            if (rect.contains((int)ev.getX(), (int)ev.getY())) return true;
        }
        return false;
    }

v.getHitRect(rect)取的的坐标是相对于父view的,但是MotionEvent的坐标是整个屏幕的,所以会导致rect.contains((int)ev.getX(), (int)ev.getY())始终返回false,即使你点击的区域是viewPager的区域 怎么修复?看下面的方法:

    private boolean isInIgnoredView(MotionEvent ev) {
        Rect rect = new Rect();
        for (View v : mIgnoredViews) {
            //v.getHitRect(rect);
            //这里稍微做了修改,v.getHitRect只能获取相对于父控件的位置,如果v嵌套在一个viewGroup中,
            // 那么添加这个v到mIgnoredViews中将不会游任何效果,例如:LinearLayout嵌套一个ViewerPager,将ViewPager加入mIgnoredViews后,依然无法接受到滑动事件
            //所以这里改为v.getGlobalVisibleRect,获取v在整个屏幕的坐标,而MotionEvent的坐标也是相对于整个屏幕来测量的
            v.getGlobalVisibleRect(rect);
            if (rect.contains((int)ev.getX(), (int)ev.getY())) return true;
        }
        return false;
    }

v.getGlobalVisibleRect(rect); 代替 v.getHitRect(rect);

更多详细信息,请看我的csdn博客:http://blog.csdn.net/fuchaosz/article/details/51513288

theBlbDan commented 8 years ago

What specific problem are you experiencing with a ViewPager? I have a ViewPager inside a RelativeLayout and have not had any problems with setOnPagerChangeListener().

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.astuetz.PagerSlidingTabStrip
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="48dip"
        android:background="@drawable/background_tabs" />

    <android.support.v4.view.ViewPager
        android:id="@+id/quicknav_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tabs" />
</RelativeLayout>
fuchaosz commented 8 years ago

@theBlbDan I'm not mean setOnPagerChangeListener(), I mean 'addIgnoreView()' is useless in somehow, for more detail, please see my csdn bolg here: http://blog.csdn.net/fuchaosz/article/details/51513288