Hello Friends, today we are going to learn an awesome functionality based on Swipe Dismiss RecyclerView. To achieve this functionality we are going to need one java class which will handle the Swipe gesture. The class you can get from this link, this is a superb class that you need to implement with your recycler view.
The java class consists of below two main things:
In this tutorial, we are going to learn how to implement swipe dismiss functionality to RecyclerView items.
1. Create a new project in Android Studio by navigating to File ⇒ New ⇒ New Project and fill required details. By default my activity is MainActivity.java.
2. Open res ⇒ values ⇒ strings.xml and add below string values. These are some strings that we are going to use in our project.
1 2 3 4 5 6 7 |
<resources> <string name="app_name">Swipe To Dismiss CardView Demo</string> <string name="swipe_dismiss_right">Swipe Dismiss Right</string> <string name="swipe_dismiss_left">Swipe Dismiss Left</string> <string name="swipe_to_dismiss">Swipe To Dismiss</string> <string name="card_view_dismiss_success">CardView Dismissed Successfully.</string> </resources> |
3. Now open up your activity_main.xml and place the below code to it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.swipetodismisscardview_demo.MainActivity"> <!-- Check box to enable and disable left/right dismiss --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <CheckBox android:id="@+id/can_dismiss_right" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:checked="true" android:gravity="center_vertical" android:text="@string/swipe_dismiss_right" android:textColor="@android:color/white" android:textSize="14sp" /> <CheckBox android:id="@+id/can_dismiss_left" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:checked="true" android:gravity="center_vertical" android:text="@string/swipe_dismiss_left" android:textColor="@android:color/white" android:textSize="14sp" /> </LinearLayout> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> |
4. For RecyclerView row items create layout naming custom_item_row_layout.xml and place the below code to it. You can use any layout here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" app:cardBackgroundColor="@android:color/white" app:cardCornerRadius="3dp" app:cardElevation="4dp" android:layout_marginTop="4dp" android:layout_marginLeft="4dp" android:layout_marginRight="4dp" app:cardUseCompatPadding="true" app:contentPadding="10dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/card_view_label" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:textColor="@android:color/black" android:textSize="15sp" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="5dp" android:text="@string/swipe_to_dismiss" android:textColor="@android:color/darker_gray" android:textSize="12sp" /> </LinearLayout> </android.support.v7.widget.CardView> |
5. Now create adapter class for RecyclerView naming RecyclerViewAdapter.java and add the below code to it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
package com.swipetodismisscardview_demo; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; /** * Created by sonu on 19/09/16. */ public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ItemViewHolder> { private static final String TAG = RecyclerViewAdapter.class.getSimpleName(); static class ItemViewHolder extends RecyclerView.ViewHolder { TextView textView; ItemViewHolder(View view) { super(view); textView = (TextView) view.findViewById(R.id.card_view_label); } } private ArrayList<String> stringArrayList; private Context context; public RecyclerViewAdapter(Context context, ArrayList<String> stringArrayList) { this.stringArrayList = stringArrayList; this.context = context; } @Override public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { return new ItemViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.custom_item_row_layout, viewGroup, false)); } @Override public void onBindViewHolder(final ItemViewHolder viewHolder, int i) { viewHolder.textView.setText(stringArrayList.get(i)); } @Override public int getItemCount() { return (null != stringArrayList ? stringArrayList.size() : 0); } } |
6. Now open your MainActivity.java class and place the below code to it. In this class you can see the implementation of SwipeableRecyclerViewTouchListener.java class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* set swipe touch listener */ SwipeableRecyclerViewTouchListener swipeTouchListener = new SwipeableRecyclerViewTouchListener(recyclerView, new SwipeableRecyclerViewTouchListener.SwipeListener() { @Override public boolean canSwipeLeft(int position) { //enable/disable left swipe on checkbox base else use true/false return dismissLeftCheck.isChecked(); } @Override public boolean canSwipeRight(int position) { //enable/disable right swipe on checkbox base else use true/false return dismissRightCheck.isChecked(); } @Override public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) { //on cardview swipe left dismiss update adapter onCardViewDismiss(reverseSortedPositions, stringArrayList, recyclerViewAdapter); } @Override public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) { //on cardview swipe right dismiss update adapter onCardViewDismiss(reverseSortedPositions, stringArrayList, recyclerViewAdapter); } }); //add item touch listener to recycler view recyclerView.addOnItemTouchListener(swipeTouchListener); |
Full Source Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package com.swipetodismisscardview_demo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.widget.CheckBox; import android.widget.Toast; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private CheckBox dismissLeftCheck, dismissRightCheck; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* find check box ids */ dismissLeftCheck = (CheckBox) findViewById(R.id.can_dismiss_left); dismissRightCheck = (CheckBox) findViewById(R.id.can_dismiss_right); setUpRecyclerView(); } /* set up recycler view */ private void setUpRecyclerView() { //find reccycler view id and set layout manager RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.setHasFixedSize(true); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(linearLayoutManager); //get string array list final ArrayList<String> stringArrayList = getListData(); //set recycler view adapter final RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(this, stringArrayList); recyclerView.setAdapter(recyclerViewAdapter); /* set swipe touch listener */ SwipeableRecyclerViewTouchListener swipeTouchListener = new SwipeableRecyclerViewTouchListener(recyclerView, new SwipeableRecyclerViewTouchListener.SwipeListener() { @Override public boolean canSwipeLeft(int position) { //enable/disable left swipe on checkbox base else use true/false return dismissLeftCheck.isChecked(); } @Override public boolean canSwipeRight(int position) { //enable/disable right swipe on checkbox base else use true/false return dismissRightCheck.isChecked(); } @Override public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) { //on cardview swipe left dismiss update adapter onCardViewDismiss(reverseSortedPositions, stringArrayList, recyclerViewAdapter); } @Override public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) { //on cardview swipe right dismiss update adapter onCardViewDismiss(reverseSortedPositions, stringArrayList, recyclerViewAdapter); } }); //add item touch listener to recycler view recyclerView.addOnItemTouchListener(swipeTouchListener); } /** * method to update array list and adapter on card view swipe dismiss left or right * * @param stringArrayList containing list of data * @param recyclerViewAdapter adapter placed over recycler view * @param reverseSortedPositions An array of positions to dismiss, sorted in descending * order for convenience. **/ private void onCardViewDismiss(int[] reverseSortedPositions, ArrayList<String> stringArrayList, RecyclerViewAdapter recyclerViewAdapter) { for (int position : reverseSortedPositions) { stringArrayList.remove(position); recyclerViewAdapter.notifyItemRemoved(position); } Toast.makeText(this, getResources().getString(R.string.card_view_dismiss_success), Toast.LENGTH_SHORT).show(); recyclerViewAdapter.notifyDataSetChanged(); } /** * method to return dummy string array list data **/ private ArrayList<String> getListData() { ArrayList<String> stringArrayList = new ArrayList<>(); for (int i = 1; i <= 20; i++) stringArrayList.add("Card View List Item : " + i); return stringArrayList; } } |
7. Finally, create a new Java class naming SwipeableRecyclerViewTouchListener.java and place the below code to it. The below class used to handle the touch events of dismiss functionality.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
package com.swipetodismisscardview_demo; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.graphics.Rect; import android.os.Build; import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPropertyAnimatorListener; import android.support.v7.widget.RecyclerView; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.ListView; import java.util.ArrayList; import java.util.Collections; import java.util.List; /* * Copyright 2013 Google Inc. * Copyright 2015 Bruno Romeu Nunes * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * A {@link View.OnTouchListener} that makes the list items in a {@link android.support.v7.widget.RecyclerView} * dismissable by swiping. * <p/> * <p>Example usage:</p> * <p/> * <pre> * SwipeDismissRecyclerViewTouchListener touchListener = * new SwipeDismissRecyclerViewTouchListener( * listView, * new SwipeDismissRecyclerViewTouchListener.OnDismissCallback() { * public void onDismiss(ListView listView, int[] reverseSortedPositions) { * for (int position : reverseSortedPositions) { * adapter.remove(adapter.getItem(position)); * } * adapter.notifyDataSetChanged(); * } * }); * listView.setOnTouchListener(touchListener); * listView.setOnScrollListener(touchListener.makeScrollListener()); * </pre> * <p/> * <p>This class Requires API level 11 or later due to use of {@link * android.view.ViewPropertyAnimator}.</p> */ class SwipeableRecyclerViewTouchListener implements RecyclerView.OnItemTouchListener { // Cached ViewConfiguration and system-wide constant values private int mSlop; private int mMinFlingVelocity; private int mMaxFlingVelocity; private long mAnimationTime; // Fixed properties private RecyclerView mRecyclerView; private SwipeListener mSwipeListener; private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero // Transient properties private List<PendingDismissData> mPendingDismisses = new ArrayList<>(); private int mDismissAnimationRefCount = 0; private float mAlpha; private float mDownX; private float mDownY; private boolean mSwiping; private int mSwipingSlop; private VelocityTracker mVelocityTracker; private int mDownPosition; private int mAnimatingPosition = ListView.INVALID_POSITION; private View mDownView; private boolean mPaused; private float mFinalDelta; private boolean mSwipingLeft; private boolean mSwipingRight; /** * Constructs a new swipe touch listener for the given {@link android.support.v7.widget.RecyclerView} * * @param recyclerView The recycler view whose items should be dismissable by swiping. * @param listener The listener for the swipe events. */ public SwipeableRecyclerViewTouchListener(RecyclerView recyclerView, SwipeListener listener) { ViewConfiguration vc = ViewConfiguration.get(recyclerView.getContext()); mSlop = vc.getScaledTouchSlop(); mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16; mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity(); mAnimationTime = recyclerView.getContext().getResources().getInteger( android.R.integer.config_shortAnimTime); mRecyclerView = recyclerView; mSwipeListener = listener; /** * This will ensure that this SwipeableRecyclerViewTouchListener is paused during list view scrolling. * If a scroll listener is already assigned, the caller should still pass scroll changes through * to this listener. */ mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { setEnabled(newState != RecyclerView.SCROLL_STATE_DRAGGING); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { } }); } /** * Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures. * * @param enabled Whether or not to watch for gestures. */ public void setEnabled(boolean enabled) { mPaused = !enabled; } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent motionEvent) { return handleTouchEvent(motionEvent); } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { // Do nothing. } @Override public void onTouchEvent(RecyclerView rv, MotionEvent motionEvent) { handleTouchEvent(motionEvent); } private boolean handleTouchEvent(MotionEvent motionEvent) { if (mViewWidth < 2) { mViewWidth = mRecyclerView.getWidth(); } switch (motionEvent.getActionMasked()) { case MotionEvent.ACTION_DOWN: { if (mPaused) { break; } // Find the child view that was touched (perform a hit test) Rect rect = new Rect(); int childCount = mRecyclerView.getChildCount(); int[] listViewCoords = new int[2]; mRecyclerView.getLocationOnScreen(listViewCoords); int x = (int) motionEvent.getRawX() - listViewCoords[0]; int y = (int) motionEvent.getRawY() - listViewCoords[1]; View child; for (int i = 0; i < childCount; i++) { child = mRecyclerView.getChildAt(i); child.getHitRect(rect); if (rect.contains(x, y)) { mDownView = child; break; } } if (mDownView != null && mAnimatingPosition != mRecyclerView.getChildLayoutPosition(mDownView)) { mAlpha = ViewCompat.getAlpha(mDownView); mDownX = motionEvent.getRawX(); mDownY = motionEvent.getRawY(); mDownPosition = mRecyclerView.getChildLayoutPosition(mDownView); mSwipingLeft = mSwipeListener.canSwipeLeft(mDownPosition); mSwipingRight = mSwipeListener.canSwipeRight(mDownPosition); if (mSwipingLeft || mSwipingRight) { mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(motionEvent); } else { mDownView = null; } } break; } case MotionEvent.ACTION_CANCEL: { if (mVelocityTracker == null) { break; } if (mDownView != null && mSwiping) { // cancel ViewCompat.animate(mDownView) .translationX(0) .alpha(mAlpha) .setDuration(mAnimationTime) .setListener(null); } mVelocityTracker.recycle(); mVelocityTracker = null; mDownX = 0; mDownY = 0; mDownView = null; mDownPosition = ListView.INVALID_POSITION; mSwiping = false; break; } case MotionEvent.ACTION_UP: { if (mVelocityTracker == null) { break; } mFinalDelta = motionEvent.getRawX() - mDownX; mVelocityTracker.addMovement(motionEvent); mVelocityTracker.computeCurrentVelocity(1000); float velocityX = mVelocityTracker.getXVelocity(); float absVelocityX = Math.abs(velocityX); float absVelocityY = Math.abs(mVelocityTracker.getYVelocity()); boolean dismiss = false; boolean dismissRight = false; if (Math.abs(mFinalDelta) > mViewWidth / 2 && mSwiping) { dismiss = true; dismissRight = mFinalDelta > 0; } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity && absVelocityY < absVelocityX && mSwiping) { // dismiss only if flinging in the same direction as dragging dismiss = (velocityX < 0) == (mFinalDelta < 0); dismissRight = mVelocityTracker.getXVelocity() > 0; } if (dismiss && mDownPosition != mAnimatingPosition && mDownPosition != ListView.INVALID_POSITION) { // dismiss final View downView = mDownView; // mDownView gets null'd before animation ends final int downPosition = mDownPosition; ++mDismissAnimationRefCount; mAnimatingPosition = mDownPosition; ViewCompat.animate(mDownView) .translationX(dismissRight ? mViewWidth : -mViewWidth) .alpha(0) .setDuration(mAnimationTime) .setListener(new ViewPropertyAnimatorListener() { @Override public void onAnimationStart(View view) { // Do nothing. } @Override public void onAnimationEnd(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { performDismiss(downView, downPosition); } } @Override public void onAnimationCancel(View view) { // Do nothing. } }); } else { // cancel ViewCompat.animate(mDownView) .translationX(0) .alpha(mAlpha) .setDuration(mAnimationTime) .setListener(null); } mVelocityTracker.recycle(); mVelocityTracker = null; mDownX = 0; mDownY = 0; mDownView = null; mDownPosition = ListView.INVALID_POSITION; mSwiping = false; break; } case MotionEvent.ACTION_MOVE: { if (mVelocityTracker == null || mPaused) { break; } mVelocityTracker.addMovement(motionEvent); float deltaX = motionEvent.getRawX() - mDownX; float deltaY = motionEvent.getRawY() - mDownY; if (!mSwiping && Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) { mSwiping = true; mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop); } if (deltaX < 0 && !mSwipingLeft) mSwiping = false; if (deltaX > 0 && !mSwipingRight) mSwiping = false; if (mSwiping) { ViewCompat.setTranslationX(mDownView, deltaX - mSwipingSlop); ViewCompat.setAlpha(mDownView, Math.max(0f, Math.min(mAlpha, mAlpha * (1f - Math.abs(deltaX) / mViewWidth)))); return true; } break; } } return false; } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void performDismiss(final View dismissView, final int dismissPosition) { // Animate the dismissed list item to zero-height and fire the dismiss callback when // all dismissed list item animations have completed. This triggers layout on each animation // frame; in the future we may want to do something smarter and more performant. final ViewGroup.LayoutParams lp = dismissView.getLayoutParams(); final int originalLayoutParamsHeight = lp.height; final int originalHeight = dismissView.getHeight(); ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { --mDismissAnimationRefCount; if (mDismissAnimationRefCount == 0) { // No active animations, process all pending dismisses. // Sort by descending position Collections.sort(mPendingDismisses); int[] dismissPositions = new int[mPendingDismisses.size()]; for (int i = mPendingDismisses.size() - 1; i >= 0; i--) { dismissPositions[i] = mPendingDismisses.get(i).position; } if (mFinalDelta < 0) { mSwipeListener.onDismissedBySwipeLeft(mRecyclerView, dismissPositions); } else { mSwipeListener.onDismissedBySwipeRight(mRecyclerView, dismissPositions); } // Reset mDownPosition to avoid MotionEvent.ACTION_UP trying to start a dismiss // animation with a stale position mDownPosition = ListView.INVALID_POSITION; ViewGroup.LayoutParams lp; for (PendingDismissData pendingDismiss : mPendingDismisses) { // Reset view presentation pendingDismiss.view.setAlpha(mAlpha); pendingDismiss.view.setTranslationX(0); lp = pendingDismiss.view.getLayoutParams(); lp.height = originalLayoutParamsHeight; pendingDismiss.view.setLayoutParams(lp); } // Send a cancel event long time = SystemClock.uptimeMillis(); MotionEvent cancelEvent = MotionEvent.obtain(time, time, MotionEvent.ACTION_CANCEL, 0, 0, 0); mRecyclerView.dispatchTouchEvent(cancelEvent); mPendingDismisses.clear(); mAnimatingPosition = ListView.INVALID_POSITION; } } }); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { lp.height = (Integer) valueAnimator.getAnimatedValue(); dismissView.setLayoutParams(lp); } }); mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView)); animator.start(); } /** * The callback interface used by {@link SwipeableRecyclerViewTouchListener} to inform its client * about a swipe of one or more list item positions. */ public interface SwipeListener { /** * Called to determine whether the given position can be swiped to the left. */ boolean canSwipeLeft(int position); /** * Called to determine whether the given position can be swiped to the right. */ boolean canSwipeRight(int position); /** * Called when the item has been dismissed by swiping to the left. * * @param recyclerView The originating {@link android.support.v7.widget.RecyclerView}. * @param reverseSortedPositions An array of positions to dismiss, sorted in descending * order for convenience. */ void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions); /** * Called when the item has been dismissed by swiping to the right. * * @param recyclerView The originating {@link android.support.v7.widget.RecyclerView}. * @param reverseSortedPositions An array of positions to dismiss, sorted in descending * order for convenience. */ void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions); } class PendingDismissData implements Comparable<PendingDismissData> { public int position; public View view; public PendingDismissData(int position, View view) { this.position = position; this.view = view; } @Override public int compareTo(@NonNull PendingDismissData other) { // Sort by descending position return other.position - position; } } } |
8. Finally, all done. Now you can also make application using Swipe Dismiss functionality.
Thanks. 🙂
Subscribe to us and get the latest news.