2016-01-05 39 views
6

Mam jeden CardView, który zawiera dwa widoki tekstu i dwa ImageView. Chcę móc przesunąć w lewo i prawo, aby "odrzucić". Właściwie chcę przesuń palcem w prawo, aby przesłać intencję, ale można to zrobić później. Na razie chcę móc zwolnić CardView przesuwając w lewo lub w prawo. Chcę również animacji przesuwania.Jak dodać funkcję przeciągania na Android CardView?

Próbowałem używać romannurik's SwipeDismissTouchListener, ale CardView nie reaguje na przesuwanie.

Jeśli ktokolwiek ma lepsze rozwiązanie niż niestandardowy słuchacz, należy go udostępnić.

Oto mój układ CardView:

<android.support.v7.widget.CardView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_below="@id/generate" 
    map:cardCornerRadius="@dimen/_3sdp" 
    map:cardElevation="@dimen/_8sdp" 
    android:id="@+id/restaurantContainer"> 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:orientation="vertical"> 

     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:orientation="horizontal"> 

      <LinearLayout 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:orientation="vertical"> 

       <ImageView 
        android:id="@+id/thumbnail" 
        android:layout_width="@dimen/_75sdp" 
        android:layout_height="@dimen/_75sdp" 
        android:layout_margin="@dimen/_5sdp" /> 

       <ImageView 
        android:id="@+id/rating" 
        android:layout_width="@dimen/_75sdp" 
        android:layout_height="@dimen/_15sdp" 
        android:layout_margin="@dimen/_5sdp" /> 
      </LinearLayout> 

      <LinearLayout 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:orientation="vertical"> 

       <TextView 
        android:id="@+id/name" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_margin="@dimen/_5sdp" 
        android:gravity="top" 
        android:textAppearance="?android:attr/textAppearanceLarge" /> 

       <TextView 
        android:id="@+id/categories" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:layout_margin="@dimen/_5sdp" 
        android:textAppearance="?android:attr/textAppearanceMedium" /> 
      </LinearLayout> 

     </LinearLayout> 

     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent"> 

      <com.google.android.gms.maps.MapView 
       android:id="@+id/mapView" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       map:cameraZoom="14" 
       map:liteMode="true" 
       map:mapType="normal" /> 

     </LinearLayout> 

    </LinearLayout> 

</android.support.v7.widget.CardView> 

Jak skonfigurować SwipeDismissTouchListener:

RelativeLayout rootLayout; 
CardView restaurantCardView; 

... 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

     rootLayout = (RelativeLayout) inflater.inflate(R.layout.fragment_main, container, false); 

     restaurantCardView = (CardView) rootLayout.findViewById(R.id.restaurantContainer); 

     restaurantCardView.setOnTouchListener(new SwipeDismissTouchListener(restaurantCardView, null, new SwipeDismissTouchListener.DismissCallbacks() { 
      @Override 
      public boolean canDismiss(Object token) { 
       Log.d("Chris", "canDismiss() called with: " + "token = [" + token + "]"); 
       return true; 
      } 

      @Override 
      public void onDismiss(View view, Object token) { 
       Log.d("Chris", "onDismiss() called with: " + "view = [" + view + "], token = [" + token + "]"); 
      } 
     })); 
    .... 

    return rootLayout; 

jestem w stanie zobaczyć dziennik z canDismiss(...) ale nie z onDismiss(...).

Odpowiedz

9

Będziesz musiał umieścić go wewnątrz RecyclerView (a CardView jako jedynego elementu tam)

Następnie użyj ItemTouchHelper.SimpleCallback do itemTouchHelper.attachToRecyclerView(recyclerView);

To daje animacje i

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

można określić konkretne działanie w oparciu o kierunek przesunięcia.

Zobacz pełną instrukcję tutaj: Swipe to Dismiss for RecyclerView

Ponadto, będziesz musiał wyłączyć przewijania pionowego w RecyclerView:

public class UnscrollableLinearLayoutManager extends LinearLayoutManager { 
    public UnscrollableLinearLayoutManager(Context context) { 
     super(context); 
    } 

    @Override 
    public boolean canScrollVertically() { 
     return false; 
    } 
} 

..... 

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); 
recyclerView.setLayoutManager(new UnscrollableLinearLayoutManager(this)); 
recyclerView.setAdapter(new RestaurantCardAdapter()); 

Inaczej - raz spróbujesz, aby przewinąć w górę lub w dół - Można by zobacz animacje na końcu listy od RecyclerView.

Upd:

Oto RecyclerView.Adapter użyłem do testu:

private class RestaurantCardAdapter extends RecyclerView.Adapter { 
    @Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     return new RestaurantViewHolder(new RestaurantCard(parent.getContext())); 
    } 

    @Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {} 

    @Override 
    public int getItemCount() { 
     return 1; 
    } 

    private class RestaurantViewHolder extends RecyclerView.ViewHolder { 
     public RestaurantViewHolder(View itemView) { 
      super(itemView); 
     } 
    } 
} 

RestaurantCard - jest po prostu zwyczaj View (rozciąga CardView w naszym przypadku):

public class RestaurantCard extends CardView { 
    public RestaurantCard(Context context) { 
     super(context); 
     initialize(context); 
    } 

    public RestaurantCard(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     initialize(context); 
    } 

    private void initialize(Context context){ 
     LayoutInflater.from(context).inflate(R.layout.card, this); 
     // ImageView imageView = (ImageView)getView.findViewById(...); 
    } 
} 
+0

Awesome, I naprawdę doceniam twoją szczegółową odpowiedź. Mam pytanie: skoro korzystam tylko z jednego CardView, jaki jest najlepszy sposób na stworzenie "CardCardCardCard"? Wszystkie przykłady online dotyczą list. Czy jest coś, co powinienem robić konkretnie? Po prostu nie chcę utknąć gdzieś i spędzać czas próbując naprawić głupie błędy haha. – ctzdev

+1

@ChrisTarazi Zaktualizowałem odpowiedź za pomocą Adaptera i ViewHolder, których użyłem do przetestowania pomysłu. Powodzenia! Wszelkie pytania - wystarczy zapytać –

+0

Mam problem z 'onCreateViewHolder (...)'. Uważam, że powinniśmy nadmuchać pogląd na podstawie tego, co widziałem online. Ponieważ w 'onBindViewHolder (...)', moje odniesienie 'RestaurantViewHolder' do' TextViews' i 'ImageViews' to' null'.Musimy więc mieć coś z poglądami, których nam brakuje. – ctzdev