6

Ich habe eine einzelne CardView, die zwei TextViews und zwei ImageViews enthält. Ich möchte in der Lage sein, nach links und rechts zu wischen, um "zu entlassen". Ich möchte eigentlich nach rechts wischen, um eine Absicht zu senden, aber das kann später gemacht werden. Für den Moment möchte ich in der Lage sein, die CardView durch Streichen nach links oder rechts zu entlassen. Ich möchte auch die Animation des Wischens.Wie Swipe-Funktionalität auf Android CardView hinzufügen?

Ich versuchte mit romannurik's SwipeDismissTouchListener, aber die CardView reagiert nicht auf Swiping.

Wenn jemand eine bessere Lösung als romannurik's benutzerdefinierte Listener hat, bitte teilen.

Hier ist mein CardView Layout:

<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> 

Wie richtet ich die 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; 

Ich bin in der Lage das Protokoll von canDismiss(...) aber nicht von onDismiss(...) zu sehen.

Antwort

9

Sie werden es in RecyclerView setzen müssen (und Ihre CardView als einziger Punkt dort)

Dann verwenden ItemTouchHelper.SimpleCallback-itemTouchHelper.attachToRecyclerView(recyclerView);

Es wird Ihnen Animationen geben und in

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

können Sie bestimmte Aktionen basierend auf der Swipe-Richtung angeben.

vollständige Anweisung Siehe hier:

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

Andernfalls - wenn Sie oder unten, um nach oben werde versuchen - würden Sie: Swipe to Dismiss for RecyclerView

Sie werden auch vertikale Scroll in RecyclerView deaktivieren müssen siehe Ende-der-Liste-Animationen RecyclerView.

Upd:

RecyclerView.Adapter Hier ich für den Test verwendet:

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 - ist nur eine benutzerdefinierte View (erweitert CardView in unserem Fall):

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 schätze deine ausführliche Antwort wirklich. Ich habe eine Frage: Da ich nur einen CardView verwende, was ist der beste Weg, um den RestaurantCardAdapter zu erstellen? Alle Beispiele online sind für Listen. Gibt es irgendetwas, was ich speziell machen sollte? Ich möchte einfach nicht irgendwo stecken bleiben und meine Zeit damit verbringen, dumme Fehler zu korrigieren, haha. – ctzdev

+1

@ChrisTarazi Ich habe die Antwort mit Adapter & ViewHolder aktualisiert, die ich zum Testen der Idee verwendet habe. Viel Glück! Irgendwelche Fragen - einfach fragen –

+0

Ich habe Probleme mit 'onCreateViewHolder (...)'. Ich denke, wir müssen eine Ansicht aufblasen, die auf dem basiert, was ich online gesehen habe. Weil in 'onBindViewHolder (...)' meine 'RestaurantViewHolder's Referenz auf die' TextViews' und 'ImageViews'' null' ist.Es muss also etwas mit den Ansichten geben, die uns fehlen. – ctzdev