Is it possible to disable SwipeRefreshLayout
drag animation on swipe down without class customization?
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.
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.
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.
Try calling:
setEnabled(false)
on your SwipeRefreshLayout view.
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:
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;
}
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With