2015-11-29 22 views
16

Próbuję zaimplementować bezstykowa aby usunąć takie same jak Gmail app „Swipe do archiwum”:Android - Swipe usunąć RecyclerView

gmail swipe delete gmail swipe delete

Próbowałem wiele tutoriali, ale żaden z nich pracuje jako szybki jak gmail, Wolę nie pracować na zewnętrznej bibliotece. Jak mogę to zrobić?

Edit:

Mój kod tak daleko

ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { 
       public boolean onMove(RecyclerView recyclerView, 
               RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
//     final int fromPos = viewHolder.getAdapterPosition(); 
//     final int toPos = viewHolder.getAdapterPosition(); 
//     // move item in `fromPos` to `toPos` in adapter. 
        return true;// true if moved, false otherwise 
       } 

      @Override 
      public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { 
       //Remove swiped item from list and notify the RecyclerView 
       mAdapter.notifyItemRemoved(viewHolder.getLayoutPosition()); 
      } 
     }; 
     ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); 
     itemTouchHelper.attachToRecyclerView(mRecyclerView); 

udało mi się włączyć gest machnięcia ale nie wiem jak dodać tło i obraz pod viewHolder. Próbowałem umieścić kolejną oprawę FrameLayout w pliku item_XXX.xml, ale po przesunięciu rzuca cały element w tle.

+1

Pomoże to: - http://stackoverflow.com/questions/27293960/swipe-to-dismiss -for-recyclerview – Wizard

+0

Powinieneś powiedzieć, co zrobiłeś do tej pory i jaki kod próbowałeś. –

+0

Zobacz http://stackoverflow.com/questions/30820806/adding-a-colored-background-with-ext-icon-under-swiped-row-when-using-androids, istnieje rozwiązanie wykorzystujące przesłonięcie onChildDraw. –

Odpowiedz

15

Musiałem to zrobić na drugi dzień i miałem pewne problemy, więc postanowiłem napisać na nim post na blogu. Nie jest wymagana żadna niezależna biblioteka.

blog post git repo

Zasadniczo, nie byłoby narysować "stan Cofnij" poprzez onChildDraw, będzie się to odbywać poprzez ViewHolder. Również nie usuniesz wiersza w onSwipe po prostu oznacz go jako "oczekujący delete" i powiadom adapter, aby ponownie go powiązał w "stanie cofania". Jednocześnie piszesz Runnable faktycznie usunięcie wiersza w X sekund, chyba że zostanie naciśnięty przycisk cofania ...

+0

Przyjemna implementacja nawet próbowałem czegoś podobnego do tego, co udało mi się osiągnąć przesunięcie w obu kierunkach [Partial Swipe] (http://stackoverflow.com/questions/34747458/partial-and-full-swipe-for-recyclerview-using-touchhelpercallback), ale możemy osiągnąć częściowe przesunięcie, po prostu pozwolić użytkownik wie, że może wykonać tę samą operację z częściowym przesunięciem palca? –

+0

Czy można to zrobić onclick zamiast onswipe? – gdubs

+0

gmail single i multiselection recyclerview longpress kontekstowy tryb działania popup do usunięcia udziału w reklamie – Harsha

14

prosty kod do RecyclerView Swipe:

 ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN | ItemTouchHelper.UP) { 

      @Override 
      public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
       Toast.makeText(ListActivity.this, "on Move", Toast.LENGTH_SHORT).show(); 
       return false; 
      } 

      @Override 
      public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { 
       Toast.makeText(ListActivity.this, "on Swiped ", Toast.LENGTH_SHORT).show(); 
       //Remove swiped item from list and notify the RecyclerView 
       int position = viewHolder.getAdapterPosition(); 
       arrayList.remove(position); 
       adapter.notifyDataSetChanged(); 

      } 
    }; 

Następnie ustaw zwrotna dla recyclerView z poniższych stwierdzeń :

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); 
itemTouchHelper.attachToRecyclerView(rv); 
0

To na pewno zadziała. Jeśli chcesz pasek z przekąskami, użyj funkcji coordinatorLayout w twoim xml. Można ustawić tło jak gmail .Jeśli masz jakieś dought wystarczy kliknąć link

https://drive.google.com/open?id=11ZOrjMMSjdskt8gG8RP52V5Al5yE50dD

ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) 

     { 

       Drawable background; 
       Drawable xMark; 
       int xMarkMargin; 
       boolean initiated; 

       private void init() { 
        background = new ColorDrawable(Color.RED); 
        xMark = ContextCompat.getDrawable(Activity.this, R.drawable.ic_delete_svg); 
        xMark.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP); 
        initiated = true; 
       } 

       @Override 
       public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
        Toast.makeText(Activity.this, "on Move", Toast.LENGTH_SHORT).show(); 
        return false; 
       } 

       @Override 
       public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { 
        /*Toast.makeText(mcontext, "on Swiped ", Toast.LENGTH_SHORT).show();*/ 

        Snackbar snackbar = Snackbar 
          .make(coordinatorLayout, "Deleted Successfully", Snackbar.LENGTH_LONG) 
          .setAction("UNDO", new View.OnClickListener() { 
           @Override 
           public void onClick(View view) { 
            Snackbar snackbar1 = Snackbar.make(coordinatorLayout, "Message is restored!", Snackbar.LENGTH_SHORT); 
            snackbar1.show(); 
           } 
          }); 

        snackbar.show(); 

        //Remove swiped item from list and notify the RecyclerView 
        int position = viewHolder.getAdapterPosition(); 
        arrayList.remove(position); 
        adapter.notifyDataSetChanged(); 

       } 

       @Override 
       public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { 
        View itemView = viewHolder.itemView; 

        // not sure why, but this method get's called for viewholder that are already swiped away 
        if (viewHolder.getAdapterPosition() == -1) { 
         // not interested in those 
         return; 
        } 

        if (!initiated) { 
         init(); 
        } 

        // draw red background 
        background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom()); 
        background.draw(c); 

        int xMarkLeft = 0; 
        int xMarkRight = 0; 
        int xMarkTop = itemView.getTop() + (itemHeight - intrinsicHeight)/2; 
        int xMarkBottom = xMarkTop + intrinsicHeight; 
        if (dX < 0) { 
         xMarkLeft = itemView.getRight() - xMarkMargin - intrinsicWidth; 
         xMarkRight = itemView.getRight() - xMarkMargin; 
        } else { 
         xMarkLeft = itemView.getLeft() + xMarkMargin; 
         xMarkRight = itemView.getLeft() + xMarkMargin + intrinsicWidth; 
        } 
        xMark.setBounds(xMarkLeft, xMarkTop, xMarkRight, xMarkBottom); 
        xMark.draw(c); 

        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); 
       } 

      }; 


      ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); 
      itemTouchHelper.attachToRecyclerView(mRecyclerView); 
Powiązane problemy