2016-04-06 17 views
1

Android uygulamaları geliştiriyorum. Uygulamamda, Recycler View kullanıyorum. Bu, Recycler View'ı ilk kullanışım. CardView ile birlikte kullanıyorum. Recycler görünümünü kullanmamın nedeni, sola veya sağa kaydırarak satırı kaldırmak istiyorum. Ancak, bunu Recycler View'da yapacak etkinliği bulamıyorum. Lütfen nasıl ayarlayabilirim? Recycler View'da yerleşik mi? BuAndroid'de kaydırarak veya kaydırarak geri dönüştürücü görünümü sırasını nasıl kaldırılır?

compile 'com.android.support:cardview-v7:23.0.+' 

compile 'com.android.support:recyclerview-v7:23.0.+' 

gibi

Ben kullanarak yüklü grandle Bu Bu benim satır düzeni

<android.support.v7.widget.CardView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    card_view:cardBackgroundColor="@color/colorAccent" 
    card_view:cardCornerRadius="10dp" 
    card_view:cardElevation="5dp" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:card_view="http://schemas.android.com/apk/res-auto"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"> 
     <TextView 
      android:id="@+id/card_name" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 

     <TextView 
      android:id="@+id/card_email" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 
    </LinearLayout> 
</android.support.v7.widget.CardView> 

benim adaptör

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.MyViewHolder> { 

    private ArrayList<CardData> values; 

    public CardAdapter(ArrayList<CardData> valuesPram) 
    { 
     this.values = valuesPram; 
    } 

    public class MyViewHolder extends RecyclerView.ViewHolder { 
     public TextView name,email; 

     public MyViewHolder(View view) { 
      super(view); 
      name = (TextView) view.findViewById(R.id.card_name); 
      email = (TextView)view.findViewById(R.id.card_email); 
     } 
    } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View itemView = LayoutInflater.from(parent.getContext()) 
       .inflate(R.layout.cards_layout, parent, false); 

     return new MyViewHolder(itemView); 
    } 

    @Override 
    public void onBindViewHolder(MyViewHolder holder, int position) { 
     CardData cardData = values.get(position); 
     holder.email.setText(cardData.getEmail()); 
     holder.name.setText(cardData.getName()); 
    } 

    @Override 
    public int getItemCount() { 
     return values.size(); 
    } 
} 

olan bu benim faaliyettir

public class MainActivity extends AppCompatActivity { 

    private RecyclerView recyclerView; 
    private RecyclerView.LayoutManager layoutManager; 
    private ArrayList<Integer> removedItems; 

    private ArrayList<CardData> listItems; 
    private CardAdapter adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     initializeData(); 
     setUpRecyclerView(); 
    } 

    private void setUpRecyclerView() 
    { 
     recyclerView = (RecyclerView)findViewById(R.id.my_recycler_view); 
     recyclerView.setHasFixedSize(true); 
     layoutManager = new LinearLayoutManager(this); 
     recyclerView.setLayoutManager(layoutManager); 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 
     recyclerView.setAdapter(adapter); 


    } 

    private void initializeData() 
    { 
     listItems = new ArrayList<CardData>(); 
     CardData item1 = new CardData(); 
     item1.setName("Name 1"); 
     item1.setEmail("Email 1"); 
     listItems.add(item1); 
     CardData item2 = new CardData(); 
     item2.setName("Name 2"); 
     item2.setEmail("Email 2"); 
     listItems.add(item2); 
     CardData item3 = new CardData(); 
     item3.setName("Name 3"); 
     item3.setEmail("Email 3"); 
     listItems.add(item3); 
     CardData item4 = new CardData(); 
     item4.setName("Name 4"); 
     item4.setEmail("Email 4"); 
     listItems.add(item4); 
     adapter = new CardAdapter(listItems); 
    } 

    private void removeItem(View v) 
    { 
     int selectedItemPosition = recyclerView.getChildPosition(v); 
     RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForPosition(selectedItemPosition); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 
} 

Kodum düzgün çalışıyor. Sorum şu; geri dönüşümcü görünümünün satırlarından birine sola veya sağa kaydırarak öğeyi kaldırmak için etkinliği nasıl uygulayabilirim?

+0

, hızlıca kaydırma görevden için her şeyi denedi mi var ?? –

+0

https://github.com/daimajia/AndroidSwipeLayout – Manifest

+0

Bir etkinlik aradım. Ama anlamadım. @RakshitNawani –

cevap

0

SwipeDismissRecyclerViewTouchListener touchListener = 
       new SwipeDismissRecyclerViewTouchListener(
         recyclerObject, 
         new SwipeDismissRecyclerViewTouchListener.DismissCallbacks() { 
          @Override 
          public boolean canDismiss(int position) { 

            return true; 

          } 

          @Override 
          public void onDismiss(RecyclerView recyclerView, int[] reverseSortedPositions) { 
           for (final int position : reverseSortedPositions) { 

            your_array.remove(position); 

           } 
           // do not call notifyItemRemoved for every item, it will cause gaps on deleting items 
           adapter.notifyDataSetChanged(); 
          } 
         }); 

     recyclerObject.setOnTouchListener(touchListener); 

SwipeDismissRecyclerViewTouchListener

import android.animation.Animator; 
import android.animation.AnimatorListenerAdapter; 
import android.animation.ValueAnimator; 
import android.graphics.Rect; 
import android.os.SystemClock; 
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.AbsListView; 
import android.widget.ListView; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class SwipeDismissRecyclerViewTouchListener 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 RecyclerView mRecyclerView; 
    private DismissCallbacks mCallbacks; 
    private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero 

    // Transient properties 
    private List<PendingDismissData> mPendingDismisses = new ArrayList<PendingDismissData>(); 
    private int mDismissAnimationRefCount = 0; 
    private float mDownX; 
    private float mDownY; 
    private boolean mSwiping; 
    private int mSwipingSlop; 
    private VelocityTracker mVelocityTracker; 
    private int mDownPosition; 
    private View mDownView; 
    private boolean mPaused; 

    /** 
    * The callback interface used by {@link coverflow.example.bala.myrecyclerview.SwipeDismissRecyclerViewTouchListener} to inform its client 
    * about a successful dismissal of one or more list item positions. 
    */ 
    public interface DismissCallbacks { 
     /** 
     * Called to determine whether the given position can be dismissed. 
     */ 
     boolean canDismiss(int position); 

     /** 
     * Called when the user has indicated they she would like to dismiss one or more list item 
     * positions. 
     * 
     * @param recyclerView    The originating {@link ListView}. 
     * @param reverseSortedPositions An array of positions to dismiss, sorted in descending 
     *        order for convenience. 
     */ 
     void onDismiss(RecyclerView recyclerView, int[] reverseSortedPositions); 
    } 

    /** 
    * Constructs a new swipe-to-dismiss touch listener for the given list view. 
    * 
    * @param recyclerView The list view whose items should be dismissable. 
    * @param callbacks The callback to trigger when the user has indicated that she would like to 
    *     dismiss one or more list items. 
    */ 
    public SwipeDismissRecyclerViewTouchListener(RecyclerView recyclerView, DismissCallbacks callbacks) { 
     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; 
     mCallbacks = callbacks; 
    } 

    /** 
    * 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 AbsListView.OnScrollListener} to be added to the {@link 
    * ListView} using {@link ListView#setOnScrollListener(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 coverflow.example.bala.myrecyclerview.SwipeDismissRecyclerViewTouchListener} is 
    * paused during list view scrolling.</p> 
    * 
    * @see coverflow.example.bala.myrecyclerview.SwipeDismissRecyclerViewTouchListener 
    */ 
    public RecyclerView.OnScrollListener makeScrollListener() { 
     return new RecyclerView.OnScrollListener() { 
      @Override 
      public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 
       setEnabled(newState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); 
      } 

      @Override 
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
      } 
     }; 
    } 

    @Override 
    public boolean onTouch(View view, MotionEvent motionEvent) { 
     if (mViewWidth < 2) { 
      mViewWidth = mRecyclerView.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 = 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) { 
        mDownX = motionEvent.getRawX(); 
        mDownY = motionEvent.getRawY(); 
        mDownPosition = mRecyclerView.getChildPosition(mDownView); 
        if (mCallbacks.canDismiss(mDownPosition)) { 
         mVelocityTracker = VelocityTracker.obtain(); 
         mVelocityTracker.addMovement(motionEvent); 
        } else { 
         mDownView = null; 
        } 
       } 
       return false; 
      } 

      case MotionEvent.ACTION_CANCEL: { 
       if (mVelocityTracker == null) { 
        break; 
       } 

       if (mDownView != null && mSwiping) { 
        // cancel 
        mDownView.animate() 
          .translationX(0) 
          .alpha(1) 
          .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; 
       } 

       float deltaX = 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(deltaX) > mViewWidth/2 && mSwiping) { 
        dismiss = true; 
        dismissRight = deltaX > 0; 
       } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity 
         && absVelocityY < absVelocityX && mSwiping) { 
        // dismiss only if flinging in the same direction as dragging 
        dismiss = (velocityX < 0) == (deltaX < 0); 
        dismissRight = mVelocityTracker.getXVelocity() > 0; 
       } 
       if (dismiss && mDownPosition != ListView.INVALID_POSITION) { 
        // dismiss 
        final View downView = mDownView; // mDownView gets null'd before animation ends 
        final int downPosition = mDownPosition; 
        ++mDismissAnimationRefCount; 
        mDownView.animate() 
          .translationX(dismissRight ? mViewWidth : -mViewWidth) 
          .alpha(0) 
          .setDuration(mAnimationTime) 
          .setListener(new AnimatorListenerAdapter() { 
           @Override 
           public void onAnimationEnd(Animator animation) { 
            performDismiss(downView, downPosition); 
           } 
          }); 
       } else { 
        // cancel 
        mDownView.animate() 
          .translationX(0) 
          .alpha(1) 
          .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 (Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX)/2) { 
        mSwiping = true; 
        mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop); 
        mRecyclerView.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)); 
        mRecyclerView.onTouchEvent(cancelEvent); 
        cancelEvent.recycle(); 
       } 

       if (mSwiping) { 
        mDownView.setTranslationX(deltaX - mSwipingSlop); 
        mDownView.setAlpha(Math.max(0f, Math.min(1f, 
          1f - 2f * Math.abs(deltaX)/mViewWidth))); 
        return true; 
       } 
       break; 
      } 
     } 
     return false; 
    } 

    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(PendingDismissData other) { 
      // Sort by descending position 
      return other.position - position; 
     } 
    } 

    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 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; 
        } 
        mCallbacks.onDismiss(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(1f); 
         pendingDismiss.view.setTranslationX(0); 
         lp = pendingDismiss.view.getLayoutParams(); 
         lp.height = originalHeight; 
         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(); 
       } 
      } 
     }); 

     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(); 
    } 
} 
3

etkinlik aşağıdaki satırı ekleyin projenize basit bir çözüm SwipeDismissRecyclerViewTouchListener bu sınıfı ekle ItemTouchHelper RecyclerView kendisi

tarafından sağlanan kullanmaktır
//Swipe to Delete 
    ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
      ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { 
     @Override 
     public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
      return false; 
     } 

     @Override 
     public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) 
     { 

      // Do Stuff 


     } 

    }); 
    swipeToDismissTouchHelper.attachToRecyclerView(recyclerView); 
1

@iPaulPro tarafından geliştirilen, ItemTouchHelper isimli küçük bir kod parçası bulunmaktadır. Mükemmel çalışır ve neredeyse RecyclerView'un sürüklenmesini ve kaydırılmasını destekler. İhtiyacınız olan tek şey 3 basit arayüzleri uygulamaktır + geri arama biraz geri yazma (basit durumlarda geri arama sınıfı sağlanan işler).

İşte link in github

İlgili konular