h6ah4i / android-advancedrecyclerview

RecyclerView extension library which provides advanced features. (ex. Google's Inbox app like swiping, Play Music app like drag and drop sorting)
https://advancedrecyclerview.h6ah4i.com/
Apache License 2.0
5.32k stars 860 forks source link

Both direction swipes with limited swipe amount #231

Open iamtodor opened 8 years ago

iamtodor commented 8 years ago

Hi! Is there a way to make the same behaviour like demo_s has but with left and right item pinned? I mean I have left and right buttons, which should get a show like your demo has.

Here the code, which I used as example: https://github.com/h6ah4i/android-advancedrecyclerview/blob/master/example/src/main/java/com/h6ah4i/android/example/advrecyclerview/demo_s_button/SwipeableWIthButtonExampleAdapter.java

Here is mine adapter with a few changes: https://gist.github.com/Iamtodor/49528adda131c13d2c716d20f3821f29

Here the screen how it should looks like: 2016-04-19 00 26 48

kostya17 commented 8 years ago

Faced the same problem. Is there a way to implement both direction swipes with limited swipe amount?

h6ah4i commented 8 years ago

@Iamtodor, @kostya17 Hi. I will show you small code snippets which helps you to implement such behavior with this library. (Sorry, I have not time to create a full example code on week days...)


First, look at the adapter implementation of the "Button under swipeable item" demo. This demo app allows left direction swipe only.

1. Change isPinned() method of each item data

// this method return whether the item is pinned or not
boolean isPinned();
👇
// this method returns NOT_PINNED(=0), PINNED_LEFT(=1) or PINNED_RIGHT(=2)
int getPinnedState();

2. Modify onBindItemView() method of the adapter


public void onBindViewHolder(MyViewHolder holder, int position) {
    ...
    holder.setMaxLeftSwipeAmount(-0.5f);
    holder.setMaxRightSwipeAmount(0);
    holder.setSwipeItemHorizontalSlideAmount(
            item.isPinned() ? -0.5f : 0);
}
👇
public void onBindViewHolder(MyViewHolder holder, int position) {
    ...
    holder.setMaxLeftSwipeAmount(-0.7f);
    holder.setMaxRightSwipeAmount(0.7f);
    switch (item.getPinnedState()) {
    case PINNED_LEFT:
        holder.setSwipeItemHorizontalSlideAmount(-0.7f);
        break;
    case PINNED_RIGHT:
        holder.setSwipeItemHorizontalSlideAmount(0.7f);
        break;
    default:
        holder.setSwipeItemHorizontalSlideAmount(0);
        break;
    }
}

3. Modify the onSwipeItem() method of the adapter

@Override
public SwipeResultAction onSwipeItem(MyViewHolder holder, int position, int result) {
    switch (result) {
        case Swipeable.RESULT_SWIPED_LEFT:
            return new SwipeLeftResultAction(this, position);
        case Swipeable.RESULT_SWIPED_RIGHT:
        case Swipeable.RESULT_CANCELED:
        default:
            if (position != RecyclerView.NO_POSITION) {
                return new UnpinResultAction(this, position);
            } else {
                return null;
            }
    }
}
👇
@Override
public SwipeResultAction onSwipeItem(MyViewHolder holder, int position, int result) {
    switch (result) {
        case Swipeable.RESULT_SWIPED_LEFT:
            return new SwipePinnedResultAction(this, position, PINNED_LEFT);
        case Swipeable.RESULT_SWIPED_RIGHT:
            return new SwipePinnedResultAction(this, position, PINNED_RIGHT);
        case Swipeable.RESULT_CANCELED:
        default:
            if (position != RecyclerView.NO_POSITION) {
                return new UnpinResultAction(this, position);
            } else {
                return null;
            }
    }
}

4. Convert SwipeLeftResultAction to SwipePinnedResultAction

private static class SwipeLeftResultAction extends SwipeResultActionMoveToSwipedDirection {
    ...
}
👇
private static class SwipePinnedResultAction extends SwipeResultActionMoveToSwipedDirection {
    private SwipeableWIthButtonExampleAdapter mAdapter;
    private final int mPosition;
    private final int mPinnedState;
    private boolean mSetPinned;

    SwipePinnedResultAction(SwipeableWIthButtonExampleAdapter adapter, int position, int pinnedState) {
        mAdapter = adapter;
        mPosition = position;
        mPinnedState = pinnedState;
    }

    @Override
    protected void onPerformAction() {
        super.onPerformAction();

        AbstractDataProvider.Data item = mAdapter.mProvider.getItem(mPosition);

        if (item.getPinnedState() == NOT_PINNED) {
            item.setPinnedState(mPinnedState);
            mAdapter.notifyItemChanged(mPosition);
            mSetPinned = true;
        }
    }

    ...
}
iamtodor commented 8 years ago

@h6ah4i Thank you, buddy. It works great!

sereja93 commented 3 years ago

@h6ah4i hello. Can you update example for last library version?