Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DrawerLayout with HorizontalScrollView into content menu

my question is simple. Can I use an HorizontalScrollView inside the content menu of a DrawerLayout? My DrawerLayout looks like this:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/pnlMenu"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- Main content view -->

    <ListView
        android:id="@+id/lst"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:fastScrollEnabled="true"
        android:focusable="true"
        android:focusableInTouchMode="true"
        tools:listitem="@layout/item_layout" >
    </ListView>

    <!-- Content of menu -->

    <FrameLayout
        android:id="@+id/drawerFrame"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:clickable="true"
        android:background="@color/black" >

        <fragment
            android:id="@+id/frag"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            class="com.test.TestFragment" />
    </FrameLayout>
</android.support.v4.widget.DrawerLayout>

Inside the fragment I have the HorizontalScrollView but when I try to touch it nothing happen because the drawer layout follow my finger. I think that disabling the touch events inside the content menu and make DrawerLayout closable only when main content view is clicked will solve my problem. Is that true? If not, can someone tell me what can I do?

Thank you.

like image 984
David Martinelli Avatar asked Mar 07 '14 09:03

David Martinelli


2 Answers

Based on this solution: https://stackoverflow.com/a/7258579/452486

I've been able to make HorizontalScrollView scrollable. Create a class extends DrawerLayout:

public class AllowChildInterceptTouchEventDrawerLayout extends DrawerLayout {

    private int mInterceptTouchEventChildId;

    public void setInterceptTouchEventChildId(int id) {
       this.mInterceptTouchEventChildId = id;
    }

    public AllowChildInterceptTouchEventDrawerLayout(Context context) {
    super(context);
    }

    public AllowChildInterceptTouchEventDrawerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        if (mInterceptTouchEventChildId > 0) {
            View scroll = findViewById(mInterceptTouchEventChildId);
            if (scroll != null) {
                Rect rect = new Rect();
                scroll.getHitRect(rect);
                if (rect.contains((int) ev.getX(), (int) ev.getY())) {
                    return false;
                }
            }
        }
        return super.onInterceptTouchEvent(ev);

        }
    }

And add the child id which you want to intercept the touch event of drawerlayout

AllowChildInterceptTouchEventDrawerLayout drawerLayout = (AllowChildInterceptTouchEventDrawerLayout) findViewById(R.id.layoutdrawer_id);
drawerLayout.setInterceptTouchEventChildId(R.id.horizontalscrollview_id);
like image 84
Arst Avatar answered Nov 14 '22 23:11

Arst


It's better to set requestDisallowInterceptTouchEvent(true) flag instead of returning false. When We have a HorizontalScrollView and below it there's another view (eg. ListView with some menu items) and we make a dynamic gesture from HorizontalScrollView area to the aforementioned ListView the app will crash with a NPE. This case happens when you open the app for the first time and go to a DrawerLayout through the hamburger icon. Use this:

if (rect.contains((int) ev.getX(), (int) ev.getY())) {     
    this.requestDisallowInterceptTouchEvent(true);
}
like image 26
Dawid Krezel Avatar answered Nov 14 '22 23:11

Dawid Krezel