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.04k forks source link

addIgnoredView : ignored view "hitrect" is in parent coordinates #451

Open tlevavasseur opened 11 years ago

tlevavasseur commented 11 years ago

Ignored View hitrect is in parent coordinates which may not start at 0;0.

I used View.getGlobalVisibleRect to make it work with my ignored view :

private boolean isInIgnoredView(MotionEvent ev) {
    Rect rect = new Rect();
    for (View v : mIgnoredViews) {
        v.getGlobalVisibleRect(rect);
        if (rect.contains((int)ev.getX(), (int)ev.getY())) return true;
    }
    return false;
}
0hao commented 11 years ago

It works!

JulienFolliot commented 11 years ago

First, sorry for my English ;)

I agree with tlevavasseur, the hitRect method returns rect regarding the parent coordinates. It works if you add the content view in ignored views list but not if you add a child view... Using View.getGlobalVisibleRect is a good solution but we have to add a global offset point to obtain the correct rect calculation :

private boolean isInIgnoredView(MotionEvent ev) {
    Rect rect = new Rect();
    for (View v : mIgnoredViews) {
        int location[] = {0,0};
        v.getLocationOnScreen(location);
        v.getGlobalVisibleRect(rect, new Point(location[0], location[1]));
        rect.offset(0, - rect.height()/2);
        if (rect.contains((int)ev.getX(), (int)ev.getY())) return true;
    }
    return false;
}

Maybe it's not the best solution but it works in my case (ignore an horizontal scrollview contained into several layouts).

Note : I added an offset because my Y rect position is defined on center (maybe because my layout is vertically centered, ths pivotY is defined on center... I don't know :D)

Starkom commented 10 years ago

Remarks to Bismuth76 comment:

  1. getGlobalVisibleRect can return false if view is not visible
  2. MotionEvent's getX() and getY() can return absolute or local coordinates (it is context-related)

So my version of method is following:

private boolean isInIgnoredView(MotionEvent ev) { Rect rect = new Rect(); for (View v : mIgnoredViews) { int[] location = {0,0}; v.getLocationOnScreen(location); if (v.getGlobalVisibleRect(rect, new Point(location[0], location[1])) && rect.contains((int)ev.getRawX(), (int)ev.getRawY())) return true; } return false; }

markjoker commented 9 years ago

nice work, It's very helpful

theBlbDan commented 9 years ago

@Starkom Please use the appropriate Markdown so that your code samples are more presentable. Thnx for your contributions.

private boolean isInIgnoredView(MotionEvent ev) {
    Rect rect = new Rect();
    for (View v : mIgnoredViews) {
        int[] location = {0,0};
        v.getLocationOnScreen(location);
        if (v.getGlobalVisibleRect(rect, new Point(location[0], location[1])) &&
                rect.contains((int)ev.getRawX(), (int)ev.getRawY())) return true;
    }
    return false;
}