swipelistview recyclerview library example cardview android android-listview slide

library - swipe recyclerview android



Android-ListView diapositiva izquierda/derecha como Samsung contacto ListView (3)

Estoy desarrollando una aplicación, y necesito un ListView como el conctact ListView de mi Samsung Galaxy S:

Cuando deslizo mi dedo hacia la derecha, puedo enviar un mensaje a este contacto.

Cuando deslizo mi dedo hacia la derecha, puedo llamar a mi contacto.

Tengo mi ListView y solo necesito la función para hacerlo ...

Gracias por adelantado.

PD: Busqué mucho y no he encontrado nada. Lo más parecido: Recurso para Android Acción deslizante izquierda / derecha leve en listview


Si desea realizar una acción al deslizar :

Echa un vistazo a SwipeActionAdapter

Es una biblioteca impresionante que permite deslizar en ambas direcciones con un Layout o Color subyacente, y realiza una acción deseada cuando se realiza el gesto deslizar / deslizar. Puede configurarlo para revelar / cambiar el diseño.

~ No he usado la aplicación Samsung Contacts, pero parece que esto es lo que quieres

SwipeActionAdapter SwipeActionAdapter

Si quieres deslizar para revelar botones accionables:

Echa un vistazo a SwipeMenuListView

En cierto sentido, es más parecido a las TableViews con capacidad de deslizamiento en iOS.

SwipeMenuListView SwipeMenuListView SwipeMenuListView


Desde otra publicación, había un enlace a este código de Google: https://gist.github.com/2980593 que provienen de esta publicación de Google+: https://plus.google.com/u/0/113735310430199015092/posts/Fgo1p5uWZLu . Esta es una funcionalidad de Deslizar para despedir.

A partir de esto, puede proporcionar su propio código Swipe-To-Action. Así que aquí está mi versión, si puedo personalizar la acción izquierda y derecha y puedes activar la animación de Descartar (esto es solo una modificación del código de Roman Nuric).

Debes incluir esta clase en tu proyecto:

public class SwipeListViewTouchListener implements View.OnTouchListener { // Cached ViewConfiguration and system-wide constant values private int mSlop; private int mMinFlingVelocity; private int mMaxFlingVelocity; private long mAnimationTime; // Fixed properties private ListView mListView; private OnSwipeCallback mCallback; private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero private boolean dismissLeft = true; private boolean dismissRight = true; // Transient properties private List < PendingSwipeData > mPendingSwipes = new ArrayList < PendingSwipeData > (); private int mDismissAnimationRefCount = 0; private float mDownX; private boolean mSwiping; private VelocityTracker mVelocityTracker; private int mDownPosition; private View mDownView; private boolean mPaused; /** * The callback interface used by {@link SwipeListViewTouchListener} to inform its client * about a successful swipe of one or more list item positions. */ public interface OnSwipeCallback { /** * Called when the user has swiped the list item to the left. * * @param listView The originating {@link ListView}. * @param reverseSortedPositions An array of positions to dismiss, sorted in descending * order for convenience. */ void onSwipeLeft(ListView listView, int[] reverseSortedPositions); void onSwipeRight(ListView listView, int[] reverseSortedPositions); } /** * Constructs a new swipe-to-action touch listener for the given list view. * * @param listView The list view whose items should be dismissable. * @param callback The callback to trigger when the user has indicated that she would like to * dismiss one or more list items. */ public SwipeListViewTouchListener(ListView listView, OnSwipeCallback callback) { ViewConfiguration vc = ViewConfiguration.get(listView.getContext()); mSlop = vc.getScaledTouchSlop(); mMinFlingVelocity = vc.getScaledMinimumFlingVelocity(); mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity(); mAnimationTime = listView.getContext().getResources().getInteger( android.R.integer.config_shortAnimTime); mListView = listView; mCallback = callback; } /** * Constructs a new swipe-to-action touch listener for the given list view. * * @param listView The list view whose items should be dismissable. * @param callback The callback to trigger when the user has indicated that she would like to * dismiss one or more list items. * @param dismissLeft set if the dismiss animation is up when the user swipe to the left * @param dismissRight set if the dismiss animation is up when the user swipe to the right * @see #SwipeListViewTouchListener(ListView, OnSwipeCallback, boolean, boolean) */ public SwipeListViewTouchListener(ListView listView, OnSwipeCallback callback, boolean dismissLeft, boolean dismissRight) { this(listView, callback); this.dismissLeft = dismissLeft; this.dismissRight = dismissRight; } /** * 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; } /** * Returns an {@link android.widget.AbsListView.OnScrollListener} to be added to the * {@link ListView} using * {@link ListView#setOnScrollListener(android.widget.AbsListView.OnScrollListener)}. * If a scroll listener is already assigned, the caller should still pass scroll changes * through to this listener. This will ensure that this * {@link SwipeListViewTouchListener} is paused during list view scrolling.</p> * * @see {@link SwipeListViewTouchListener} */ public AbsListView.OnScrollListener makeScrollListener() { return new AbsListView.OnScrollListener() {@ Override public void onScrollStateChanged(AbsListView absListView, int scrollState) { setEnabled(scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } @ Override public void onScroll(AbsListView absListView, int i, int i1, int i2) {} }; } @ Override public boolean onTouch(View view, MotionEvent motionEvent) { if (mViewWidth < 2) { mViewWidth = mListView.getWidth(); } switch (motionEvent.getActionMasked()) { case MotionEvent.ACTION_DOWN: { if (mPaused) { return false; } // TODO: ensure this is a finger, and set a flag // Find the child view that was touched (perform a hit test) Rect rect = new Rect(); int childCount = mListView.getChildCount(); int[] listViewCoords = new int[2]; mListView.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 = mListView.getChildAt(i); child.getHitRect(rect); if (rect.contains(x, y)) { mDownView = child; break; } } if (mDownView != null) { mDownX = motionEvent.getRawX(); mDownPosition = mListView.getPositionForView(mDownView); mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(motionEvent); } view.onTouchEvent(motionEvent); return true; } case MotionEvent.ACTION_UP: { if (mVelocityTracker == null) { break; } float deltaX = motionEvent.getRawX() - mDownX; mVelocityTracker.addMovement(motionEvent); mVelocityTracker.computeCurrentVelocity(500); // 1000 by defaut but it was too much float velocityX = Math.abs(mVelocityTracker.getXVelocity()); float velocityY = Math.abs(mVelocityTracker.getYVelocity()); boolean swipe = false; boolean swipeRight = false; if (Math.abs(deltaX) > mViewWidth / 2) { swipe = true; swipeRight = deltaX > 0; } else if (mMinFlingVelocity <= velocityX && velocityX <= mMaxFlingVelocity && velocityY < velocityX) { swipe = true; swipeRight = mVelocityTracker.getXVelocity() > 0; } if (swipe) { // sufficent swipe value final View downView = mDownView; // mDownView gets null''d before animation ends final int downPosition = mDownPosition; final boolean toTheRight = swipeRight; ++mDismissAnimationRefCount; mDownView.animate() .translationX(swipeRight ? mViewWidth : -mViewWidth) .alpha(0) .setDuration(mAnimationTime) .setListener(new AnimatorListenerAdapter() {@ Override public void onAnimationEnd(Animator animation) { performSwipeAction(downView, downPosition, toTheRight, toTheRight ? dismissRight : dismissLeft); } }); } else { // cancel mDownView.animate() .translationX(0) .alpha(1) .setDuration(mAnimationTime) .setListener(null); } mVelocityTracker = null; mDownX = 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; if (Math.abs(deltaX) > mSlop) { mSwiping = true; mListView.requestDisallowInterceptTouchEvent(true); // Cancel ListView''s touch (un-highlighting the item) MotionEvent cancelEvent = MotionEvent.obtain(motionEvent); cancelEvent.setAction(MotionEvent.ACTION_CANCEL | (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT)); mListView.onTouchEvent(cancelEvent); } if (mSwiping) { mDownView.setTranslationX(deltaX); mDownView.setAlpha(Math.max(0f, Math.min(1f, 1f - 2f * Math.abs(deltaX) / mViewWidth))); return true; } break; } } return false; } class PendingSwipeData implements Comparable < PendingSwipeData > { public int position; public View view; public PendingSwipeData(int position, View view) { this.position = position; this.view = view; } @ Override public int compareTo(PendingSwipeData other) { // Sort by descending position return other.position - position; } } private void performSwipeAction(final View swipeView, final int swipePosition, boolean toTheRight, boolean dismiss) { // 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 = swipeView.getLayoutParams(); final int originalHeight = swipeView.getHeight(); final boolean swipeRight = toTheRight; ValueAnimator animator; if (dismiss) animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime); else animator = ValueAnimator.ofInt(originalHeight, 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(mPendingSwipes); int[] swipePositions = new int[mPendingSwipes.size()]; for (int i = mPendingSwipes.size() - 1; i >= 0; i--) { swipePositions[i] = mPendingSwipes.get(i).position; } if (swipeRight) mCallback.onSwipeRight(mListView, swipePositions); else mCallback.onSwipeLeft(mListView, swipePositions); ViewGroup.LayoutParams lp; for (PendingSwipeData pendingDismiss: mPendingSwipes) { // Reset view presentation pendingDismiss.view.setAlpha(1f); pendingDismiss.view.setTranslationX(0); lp = pendingDismiss.view.getLayoutParams(); lp.height = originalHeight; pendingDismiss.view.setLayoutParams(lp); } mPendingSwipes.clear(); } } }); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@ Override public void onAnimationUpdate(ValueAnimator valueAnimator) { lp.height = (Integer) valueAnimator.getAnimatedValue(); swipeView.setLayoutParams(lp); } }); mPendingSwipes.add(new PendingSwipeData(swipePosition, swipeView)); animator.start(); } }

Desde allí, puede agregar el siguiente código a su onCreate en la Actividad con el ListView:

// Create a ListView-specific touch listener. ListViews are given special treatment because // by default they handle touches for their list items... i.e. they''re in charge of drawing // the pressed state (the list selector), handling list item clicks, etc. SwipeListViewTouchListener touchListener = new SwipeListViewTouchListener( listView, new SwipeListViewTouchListener.OnSwipeCallback() { @Override public void onSwipeLeft(ListView listView, int [] reverseSortedPositions) { // Log.i(this.getClass().getName(), "swipe left : pos="+reverseSortedPositions[0]); // TODO : YOUR CODE HERE FOR LEFT ACTION } @Override public void onSwipeRight(ListView listView, int [] reverseSortedPositions) { // Log.i(ProfileMenuActivity.class.getClass().getName(), "swipe right : pos="+reverseSortedPositions[0]); // TODO : YOUR CODE HERE FOR RIGHT ACTION } }, true, // example : left action = dismiss false); // example : right action without dismiss animation listView.setOnTouchListener(touchListener); // Setting this scroll listener is required to ensure that during ListView scrolling, // we don''t look for swipes. listView.setOnScrollListener(touchListener.makeScrollListener());

Editar: para agregar una modificación de color al deslizar, su código debe estar en el case MotionEvent.ACTION_MOVE cerca de mDownView.setAlpha .


Lo que podrías hacer aquí es crear una nueva vista especialmente para la vista de lista (llámala ListViewFlinger o algo así). Luego, en esta vista, anule su método onTouchEvent y coloque algún código allí para determinar un gesto de deslizamiento. Una vez que tenga el gesto de deslizar, ejecute un evento onSlideComplete (tendrá que hacer que el oyente) sea un voialla, un ListView con contenido activado por diapositivas.

float historicX = Float.NaN, historicY = Float.NaN; static final TRIGGER_DELTA = 50; // Number of pixels to travel till trigger @Override public boolean onTouchEvent(MotionEvent e) { switch (e.getAction()) { case MotionEvent.ACTION_DOWN: historicX = e.getX(); historicY = e.getY(); break; case MotionEvent.ACTION_UP: if (e.getX() - historicX > -TRIGGER_DELTA) { onSlideComplete(Direction.LEFT); return true; } else if (e.getX() - historicX > TRIGGER_DELTA) { onSlideComplete(Direction.RIGHT); return true; } break; default: return super.onTouchEvent(e); } } enum Direction { LEFT, RIGHT; } interface OnSlideCompleteListener { void onSlideComplete(Direction dir); }