mdupls
mdupls

Reputation: 2012

SlidingDrawer determine if drawer was pulled out and pushed back before fully opening

I'm trying to make use of the SlidingDrawer ViewGroup but I've run into a few roadblocks. There are some listeners we can attach to a SlidingDrawer:

OnDrawerScrollListener
OnDrawerOpenListener
OnDrawerCloseListener

onScrollStarted() is called when the SlidingDrawer handle is initially pulled.

onScrollEnded() is called when the user has stopped tracking their finger on the handle (surprisingly not after the animation has ended).

onDrawerOpened() is called only when the user has lifted their finger and the drawer has animated fully open.

onDrawerClosed() is called only when the user has lifted their finger and the drawer has animated fully closed.

I want to disable the main view of my Activity the moment the drawer is starting to open (which can be done onScrollStarted()). When the drawer is closed I want to enable the main view of my Activity. If the user drags the drawer half open and then (without lifting their finger) drags the drawer completely closed again, then I have no idea how to determine whether to enable the main view again since onDrawerClosed() is not called. I can't just enable the main view in onScrollEnded() because that method is called just before the drawer is fully opened or fully closed.

The order of calls within the 3 listeners I mentioned is:

onScrollStarted() onScrollEnded() onDrawerOpened() / onDrawerClosed()

So clearly, in the onScroll methods there is no way to determine whether the drawer is "opening" or "closing" unless I listen for touch events. Is there a way I can do this that won't be so messy?

Thanks.

EDIT: here is my code snippet.

private boolean mDrawerScrolling = false;

    @Override
    public void onDrawerOpened() {
        Log.d(TAG, "onDrawerOpened");
    }

    @Override
    public void onDrawerClosed() {
        mViewPager.setScrollEnabled(true);

        Log.d(TAG, "onDrawerClosed");

        final View view = (View) mDrawer.getTag();
        if (view != null) {
            final Animator fadeInAnimation = AnimatorInflater.loadAnimator(
                    InboxActivity.this, R.animator.fade_out);
            fadeInAnimation.setTarget(view);
            fadeInAnimation.addListener(new AnimatorListenerAdapter() {

                @Override
                public void onAnimationEnd(Animator animation) {
                    removeView();
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    removeView();
                }

                private void removeView() {
                    ViewGroup container = (ViewGroup) findViewById(R.id.container);

                    container.removeView(view);
                }

            });
            fadeInAnimation.start();

            mDrawer.setTag(null);
        }
    }

    @Override
    public void onScrollEnded() {
        mDrawerScrolling = false;

        int left = mDrawer.getHandle().getLeft();

        Log.d(TAG, "onScrollEnded() " + left);
    }

    @Override
    public void onScrollStarted() {
        mDrawerScrolling = true;
        mCanHide = false;

        Log.d(TAG, "onScrollStarted");

        /*
         * Open the drawer if it is not open yet.
         */
        if (mDrawer.getTag() == null) {
            final View dimView = getLayoutInflater().inflate(
                    R.layout.drawer_outer, null);
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.MATCH_PARENT,
                    RelativeLayout.LayoutParams.MATCH_PARENT);
            dimView.setLayoutParams(params);
            dimView.setOnTouchListener(this);

            final ViewGroup container = (ViewGroup) findViewById(R.id.container);
            container.addView(dimView);
            container.bringChildToFront(mDrawer);

            final Animator fadeInAnimation = AnimatorInflater.loadAnimator(
                    InboxActivity.this, R.animator.fade_in);
            fadeInAnimation.setTarget(dimView);
            fadeInAnimation.start();

            mDrawer.setTag(dimView);
        }
    }

Upvotes: 1

Views: 5508

Answers (2)

TIER 0011
TIER 0011

Reputation: 1033

I was having a similar problem sometime ago and managed to create a simply solution which uses the setOnDrawerScrollListener(), isMoving(), isOpened(), Runnable(), Handler(), and Thread() classes. I have posted my solution and comments below.

    mSlidingDrawer.setOnDrawerScrollListener(new OnDrawerScrollListener() {

        private Runnable mRunnable = new Runnable() {

            @Override
            public void run() {
                // While the SlidingDrawer is moving; do nothing.
                while (mSlidingDrawer.isMoving())
                {
                    // Allow another thread to process its instructions.
                    Thread.yield();
                }

                // When the SlidingDrawer is no longer moving; trigger mHandler.
                mHandler.sendEmptyMessage(0);
            }
        };

        private Handler mHandler = new Handler() {

            public void handleMessage(Message msg) {

                if (mSlidingDrawer.isOpened()) {
                    // TODO: Case 1 - If the SlidingDrawer is completely opened...
                }
                else {
                    // TODO: Case 2 - If the SlidingDrawer is completely closed...
                }
            }
        };

        @Override
        public void onScrollEnded() {
            new Thread(mRunnable).start();
        }

        @Override
        public void onScrollStarted() {
            // TODO: When the user beings to scroll the SlidingDrawer...
        }
    });

Note: Replace the reference mSlidingDrawer with a reference to the SlidingDrawer you would like these instructions to execute on.

Upvotes: 3

Orlymee
Orlymee

Reputation: 2357

How about using other state functions in the slidingdrawer class in combination with what you have done so far. I am thinking use functions such as isOpened or isMoving. You can call these in the inScrollEnded to figure out what is the state of the drawer and take actions accordingly.

Upvotes: 1

Related Questions