-
Notifications
You must be signed in to change notification settings - Fork 862
Tutorial How to add SWIPEABLE feature to your adapter
Haruki Hasegawa edited this page Mar 27, 2016
·
4 revisions
This step is very important. If adapter does not return stable & unique ID, it will cause weird behaviors (wrong animation, NPE, etc...)
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
MyAdapter() {
setHasStableIds(true);
}
@Override
public long getItemId(int position) {
return mItems.get(position).getId(); // requires static value, it means need to keep the same value even if the item position has been changed.
}
}
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
...
static class MyViewHolder extends RecyclerView.ViewHolder {
...
}
}
⬇️ ⬇️ ⬇️
class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>
extends RecyclerView.Adapter<MyAdapter.MyViewHolder>
implements SwipeableItemAdapter<MyAdapter.MyViewHolder> {
// NOTE: Make accessible with short name
private interface Swipeable extends SwipeableItemConstants {
}
...
@Override
public int onGetSwipeReactionType(MyViewHolder holder, int position, int x, int y) {
// TODO implement here later
return Swipeable.REACTION_CAN_NOT_SWIPE_ANY;
}
@Override
public void onSetSwipeBackground(MyViewHolder holder, int position, int type) {
// TODO implement here later
}
@Override
public SwipeResultAction onSwipeItem(MyViewHolder holder, final int position, int result) {
// TODO implement here later
return new SwipeResultActionDefault();
}
static class MyViewHolder extends RecyclerView.ViewHolder {
...
}
}
class MyAdapter ... {
...
static class MyViewHolder extends RecyclerView.ViewHolder {
...
public MyViewHolder(View v) {
super(v);
...
}
...
}
}
⬇️ ⬇️ ⬇️
class MyAdapter ... {
...
public static class MyViewHolder extends AbstractSwipeableItemViewHolder {
...
public MyViewHolder(View v) {
super(v);
...
}
@Override
public View getSwipeableContainerView() {
// TODO implement here later
return null;
}
...
}
}
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center"/>
⬇️ ⬇️ ⬇️
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="56dp">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_gravity="top|left"
android:gravity="center"/>
</FrameLayout>
</FrameLayout>
class MyAdapter ... {
...
public static class MyViewHolder extends AbstractSwipeableItemViewHolder {
TextView mText;
public MyViewHolder(View v) {
super(v);
mText = (TextView) v;
}
@Override
public View getSwipeableContainerView() {
// TODO implement here later
return null;
}
...
}
}
⬇️ ⬇️ ⬇️
class MyAdapter ... {
...
public static class MyViewHolder extends AbstractSwipeableItemViewHolder {
TextView mTextView;
FrameLayout mContainer;
public MyViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(android.R.id.text1);
mContainer = (FrameLayout) v.findViewById(R.id.container);
}
@Override
public View getSwipeableContainerView() {
return mContainer;
}
...
}
}
class MyAdapter ... {
...
@Override
public int onGetSwipeReactionType(MyViewHolder holder, int position, int x, int y) {
...
}
@Override
public void onSetSwipeBackground(MyViewHolder holder, int position, int type) {
...
}
@Override
public SwipeResultAction onSwipeItem(MyViewHolder holder, int position, int result) {
...
}
static class MyViewHolder ... {
...
}
}
⬇️ ⬇️ ⬇️
class MyAdapter ... {
...
@Override
public int onGetSwipeReactionType(MyViewHolder holder, int position, int x, int y) {
// Make swipeable to LEFT direction
return Swipeable.REACTION_CAN_SWIPE_LEFT;
}
@Override
public void onSetSwipeBackground(MyViewHolder holder, int position, int type) {
// You can set background color to holder.itemView.
// The argument "type" can be one of the followings;
// - Swipeable.DRAWABLE_SWIPE_NEUTRAL_BACKGROUND
// - Swipeable.DRAWABLE_SWIPE_LEFT_BACKGROUND
// (- Swipeable.DRAWABLE_SWIPE_UP_BACKGROUND)
// (- Swipeable.DRAWABLE_SWIPE_RIGHT_BACKGROUND)
// (- Swipeable.DRAWABLE_SWIPE_DOWN_BACKGROUND)
}
@Override
public SwipeResultAction onSwipeItem(MyViewHolder holder, int position, int result) {
// Return sub class of the SwipeResultAction.
// Base (abstract) classes are
// - SwipeResultActionDefault
// - SwipeResultActionMoveToSwipedDirection
// - SwipeResultActionRemoveItem
// The argument "result" can be one of the followings;
//
// - Swipeable.RESULT_CANCELED
// - Swipeable.RESULT_SWIPED_LEFT
// (- Swipeable.RESULT_SWIPED_UP)
// (- Swipeable.RESULT_SWIPED_RIGHT)
// (- Swipeable.RESULT_SWIPED_DOWN)
if (result == Swipeable.RESULT_LEFT) {
return new SwipeResultActionMoveToSwipedDirection() {
// You can override these three methods
// - void onPerformAction()
// - void onSlideAnimationEnd()
// - void onCleanUp()
};
} else {
return new SwipeResultActionDefault();
}
}
static class MyViewHolder ... {
...
}
}
void onCreate() {
...
RecyclerView recyclerView = findViewById(R.id.recyclerView);
MyAdapter adapter = new MyAdapter();
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
⬇️ ⬇️ ⬇️
void onCreate() {
...
RecyclerView recyclerView = findViewById(R.id.recyclerView);
RecyclerViewSwipeManager swipeManager = new RecyclerViewSwipeManager();
MyAdapter adapter = new MyAdapter();
RecyclerView.Adapter wrappedAdapter = swipeManager.createWrappedAdapter(adapter);
recyclerView.setAdapter(wrappedAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
swipeManager.attachRecyclerView(recyclerView);
}
Please refer to the example app implementation.