Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwipeRefreshLayout disable drag animation on swipe down

Is it possible to disable SwipeRefreshLayout drag animation on swipe down without class customization?

like image 955
Alexander Zhak Avatar asked Sep 28 '14 19:09

Alexander Zhak


People also ask

How to disable SwipeRefreshLayout in android?

If an activity wishes to show just the progress animation, it should call setRefreshing(true). To disable the gesture and progress animation, call setEnabled(false) on the view.

What is swipe refresh layout?

Android SwipeRefreshLayout is a ViewGroup that can hold only one scrollable child. It can be either a ScrollView, ListView or RecyclerView. The basic need for a SwipeRefreshLayout is to allow the users to refresh the screen manually. This is pretty common in the Facebook Newsfeed screen.

How do you swipe to refresh on Android?

Android provides a widget that implements the swipe-to-refresh design pattern, which allows the user to trigger an update with a vertical swipe. This is implemented by the SwipeRefreshLayout widget, which detects the vertical swipe, displays a distinctive progress bar, and triggers callback methods in your app.


3 Answers

Try calling:

setEnabled(false)

on your SwipeRefreshLayout view.

like image 142
carloshwa Avatar answered Oct 14 '22 14:10

carloshwa


Well, disabling SwipeLayoutAnimanion appeared to be a rather simple task, but it involves replication of android.support.v4.widget.SwipeRefreshLayout class inside one's project.

Diving in source code will reveal, that SwipeRefreshLayout consists of three classes:

  • android.support.v4.widget.SwipeRefreshLayout
  • android.support.v4.widget.SwipeProgressBar
  • android.support.v4.widget.BakedBezierInterpolator

All three classes should be included in the project. Then SwipeRefreshLayout can be customized as follows:

Add a new public method which will control either layout should follow the swipe down gesture or not:

private boolean mLayoutMovementEnabled = true;

public void setLayoutMovementEnabled(boolean enabled) {
    mLayoutMovementEnabled = enabled;
}

All related computations are performed inside onTouchEvent(). To disable layout following the movement,

updateContentOffsetTop((int) (offsetTop)); string should be changed to

if (mLayoutMovementEnabled) updateContentOffsetTop((int) (offsetTop));

The complete modified routine is below.

@Override
public boolean onTouchEvent(MotionEvent event) {
    final int action = event.getAction();
    boolean handled = false;
    switch (action) {
        case MotionEvent.ACTION_DOWN:
            mCurrPercentage = 0;
            mDownEvent = MotionEvent.obtain(event);
            mPrevY = mDownEvent.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            if (mDownEvent != null && !mReturningToStart) {
                final float eventY = event.getY();
                float yDiff = eventY - mDownEvent.getY();
                if (yDiff > mTouchSlop) {
                    // User velocity passed min velocity; trigger a refresh
                    if (yDiff > mDistanceToTriggerSync) {
                        // User movement passed distance; trigger a refresh
                        startRefresh();
                        handled = true;
                        break;
                    } else {
                        // Just track the user's movement
                        setTriggerPercentage(
                                mAccelerateInterpolator.getInterpolation(
                                        yDiff / mDistanceToTriggerSync));
                        float offsetTop = yDiff;
                        if (mPrevY > eventY) {
                            offsetTop = yDiff - mTouchSlop;
                        }
                        if (mLayoutMovementEnabled) updateContentOffsetTop((int) (offsetTop));
                        if (mPrevY > eventY && (mTarget.getTop() < mTouchSlop)) {
                            // If the user puts the view back at the top, we
                            // don't need to. This shouldn't be considered
                            // cancelling the gesture as the user can restart from the top.
                            removeCallbacks(mCancel);
                        } else {
                            updatePositionTimeout();
                        }
                        mPrevY = event.getY();
                        handled = true;
                    }
                }
            }
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            if (mDownEvent != null) {
                mDownEvent.recycle();
                mDownEvent = null;
            }
            break;
    }
    return handled;
}
like image 32
Alexander Zhak Avatar answered Oct 14 '22 14:10

Alexander Zhak


One simple way to disable the swipe is to set the distance to trigger sync to some value too high to be reached.

mSwipeLayout.setDistanceToTriggerSync(999999);
like image 24
Sylvain Pennec Avatar answered Oct 14 '22 16:10

Sylvain Pennec