20

I want to use a seekbar in a Navigation Drawer

Basically I need to slide left and right to set the seekbar and, well, you guessed it, it slides the navigation drawer...

What I would like to do is to slide the seekbar when it's focused and the navigationdrawer when it's not.

How should I do that?

Here is my code when setting an item (I haven't set the seekbar yet)

private View onCritereView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View mView = inflater.inflate(R.layout.fragment_critere, container, false);
    LinearLayout mLinearLayout = (LinearLayout) mView.findViewById(R.id.critere_linearlayout);

    View mViewElement = inflater.inflate(R.layout.item_critere, null);
    ((TextView)mViewElement.findViewById(R.id.critere_title)).setText("Prix Maximum");

    mLinearLayout.addView(mViewElement);

    return mView;
}

Here is the item_critere.xml with the seekbar:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/critere_item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:stretchColumns="*">

    <TableRow
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="Large Text"
                android:id="@+id/critere_title"
                android:layout_gravity="left|center_vertical"
                android:layout_column="0"/>

        <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/critere_qualifier"
                android:layout_column="1"
                android:layout_span="4"/>
    </TableRow>

    <TableRow
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:text="Medium Text"
                android:id="@+id/critere_value"
                android:layout_span="4"/>
    </TableRow>

</TableLayout>

Thanks in advance :)

yprez
  • 14,854
  • 11
  • 55
  • 70
nsvir
  • 8,781
  • 10
  • 32
  • 47

2 Answers2

37

Just add an onTouchListener. When you touch the screen on the seekbar (action_down) disallow parent to intercept the event.

seekbar.setOnTouchListener(new ListView.OnTouchListener() 
{
    @Override
    public boolean onTouch(View v, MotionEvent event) 
    {
        int action = event.getAction();
        switch (action) 
        {
        case MotionEvent.ACTION_DOWN:
            // Disallow Drawer to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(true);
            break;

        case MotionEvent.ACTION_UP:
            // Allow Drawer to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(false);
            break;
        }

        // Handle seekbar touch events.
        v.onTouchEvent(event);
        return true;
    }
});
yprez
  • 14,854
  • 11
  • 55
  • 70
dumazy
  • 13,857
  • 12
  • 66
  • 113
  • This was actually copied for using ListViews inside a ScrollView. So it's new SeekBar.OnTouchListener instead of ListView.onTouchListener. It's a really easy way and it works for a lot of these sorts of problems – dumazy Aug 23 '13 at 11:29
  • Ok harder now.. x) I added a scrollview between the navigation drawer and the seekbar. I want only disable the interceptTouch event of the navigation drawer and not the scrollview x) Is that possible ? – nsvir Aug 23 '13 at 11:56
  • so you have a vertical scrollbar with horizontal seekbars in your drawer, right? – dumazy Aug 23 '13 at 12:00
  • I think it should work just fine, without having to do further implementation. If you touch the seekbar, the event will be caught for the seekbar only. If you touch somewhere else in the scrollview, things will just go as they should – dumazy Aug 23 '13 at 12:05
  • Arf nop :/ The scroll works with the navigation drawer. It distinguish horizontal / vertical motion. But on a seekbar the horizontal motion isn't caught neither of the seekbar or the navigationdrawer. – nsvir Aug 23 '13 at 12:12
  • http://stackoverflow.com/questions/18403127/catch-vertical-slide-motion-on-seekbar – nsvir Aug 23 '13 at 12:40
  • no need to handle up event its working without it. Also what is the purpose of this ` v.onTouchEvent(event);`? – Muhammad Babar Feb 13 '15 at 18:09
0

Use DrawerLayout.setDrawerLockMode

instead of ViewParent.requestDisallowInterceptTouchEvent.

In @dumazy answer requestDisallowInterceptTouchEvent solves this issue but it also creates another.

While you are scrolling on navigation drawer, If you touch on SeekBar, OnSeekBarChangeListener will trigger. So scrolling event will break and seekbar progress will start to change by moving your finger.

I modified the original answer a little bit to solve this issue using DrawerLockMode:

mSeekBar.setOnTouchListener(new SeekBar.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        switch (action) {

            case MotionEvent.ACTION_DOWN:
                // Disallow Drawer to intercept touch events.
                // v.getParent().requestDisallowInterceptTouchEvent(true);
                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // Allow Drawer to intercept touch events.
                // v.getParent().requestDisallowInterceptTouchEvent(false);
                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNDEFINED);
                break;
        }

        // Handle SeekBar touch events.
        v.onTouchEvent(event);
        return true;
    }
});
S.R
  • 2,819
  • 2
  • 22
  • 49