A Tinder Style Swipeable Deck Card View for Android
Swipeable cards are in fact gaining a lot of popularity. Especially in terms of mobile applications, swipeable makes it easier to navigate easily from one thing to another. Mainly, the swipeable style is used to interchange between images or certain contents. In both manners, this actually helps in easy navigation and also provides users with a great time. Similarly, we’re here with an astonishing tinder style swipeable deck card view. This one is focused for android developers.
This design has great functionality in terms of swiping the cards as in Tinder. In addition, it also offers indications to be added in the card. Altogether, the design and animation are really astounding. With some easy installation steps, you will have access to this design. If you’re trying to develop a social media platform or image collection using the card view. This project design might be a great implementation in your project.
Furthermore, this has great potential in terms of engaging users in your application. The preview of the design is made available below in the feature section. Briefly, talking about the design, it is similar to the tinder where you swipe the card content left or right. The code identifies the drag of the user and simply repositions other card content while removing the very top card.
Installation
In your repositories and dependencies section add these parameters:
dependencies {
compile 'com.daprlabs.aaron:cardstack:0.3.1-beta0'
}
Sync Gradle and import Swipe-Deck into your project
import com.daprlabs.cardstack.SwipeDeck;
Example
Start by defining a card view, this can be made in the normal way in XML:
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_height="wrap_content" android:layout_width="match_parent" card_view:cardCornerRadius="6dp" card_view:cardElevation="10dp" > <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="200dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Test Text" android:id="@+id/textView" android:layout_gravity="center_horizontal" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Large Text" android:id="@+id/textView2" android:layout_gravity="center_horizontal" /> </LinearLayout> </android.support.v7.widget.CardView>
You can use any type of view you like (not just a Card View) but i would recommend adding a drop shadow or border of some kind.
Next Swipe Deck takes an adapter just like you're used to with other adapter views. Here's a quick sample adapter:
public class SwipeDeckAdapter extends BaseAdapter { private List<String> data; private Context context; public SwipeDeckAdapter(List<String> data, Context context) { this.data = data; this.context = context; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(v == null){ LayoutInflater inflater = getLayoutInflater(); // normally use a viewholder v = inflater.inflate(R.layout.test_card, parent, false); } ((TextView) v.findViewById(R.id.textView2)).setText(data.get(position)); v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String item = (String)getItem(position); Log.i("MainActivity", item); } }); return v; } }
Now we add a swipe deck to our layout:
<?xml version="1.0" encoding="utf-8"?> <com.daprlabs.cardstack.SwipeFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:swipedeck="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.daprlabs.cardstack.SwipeDeck android:id="@+id/swipe_deck" android:layout_width="match_parent" android:layout_height="480dp" android:padding="20dp" swipedeck:card_spacing="10dp" swipedeck:max_visible="3" swipedeck:render_above="true" swipedeck:rotation_degrees="15" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="Button" /> </com.daprlabs.cardstack.SwipeFrameLayout>
Now we simply give our card deck an adapter and perhaps a callback from our Activity:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_swipe_deck); cardStack = (SwipeDeck) findViewById(R.id.swipe_deck); final ArrayList<String> testData = new ArrayList<>(); testData.add("0"); testData.add("1"); testData.add("2"); testData.add("3"); testData.add("4"); final SwipeDeckAdapter adapter = new SwipeDeckAdapter(testData, this); cardStack.setAdapter(adapter); cardStack.setEventCallback(new SwipeDeck.SwipeEventCallback() { @Override public void cardSwipedLeft(int position) { Log.i("MainActivity", "card was swiped left, position in adapter: " + position); } @Override public void cardSwipedRight(int position) { Log.i("MainActivity", "card was swiped right, position in adapter: " + position); } @Override public void cardsDepleted() { Log.i("MainActivity", "no more cards"); } });
Easily design cards and deck container in XML and have cards render over the top (or underneath) elements in your layout
<?xml version="1.0" encoding="utf-8"?>
<com.daprlabs.cardstack.SwipeFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swipedeck="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.daprlabs.cardstack.SwipeDeck
android:id="@+id/swipe_deck"
android:layout_width="match_parent"
android:layout_height="480dp"
android:padding="40dp"
swipedeck:card_spacing="10dp"
swipedeck:max_visible="3"
swipedeck:render_above="true"
swipedeck:rotation_degrees="15"
swipedeck:opacity_end="0.33"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="Button" />
</com.daprlabs.cardstack.SwipeFrameLayout>
Indicator images for swiping left and right, simply add a left and right swipe view to your card layout and register their resource
id with swipe deck:
<ImageView
android:id="@+id/left_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/left_arrow"
android:layout_alignTop="@+id/imageView"
android:layout_toLeftOf="@+id/imageView"
android:layout_toStartOf="@+id/imageView" />
<ImageView
android:id="@+id/right_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/right_arrow"
android:layout_below="@+id/offer_image"
android:layout_toRightOf="@+id/imageView"
android:layout_toEndOf="@+id/imageView" />
final SwipeDeckAdapter adapter = new SwipeDeckAdapter(testData, this);
cardStack.setAdapter(adapter);
cardStack.setLeftImage(R.id.left_image);
cardStack.setRightImage(R.id.right_image);
<ImageView
android:id="@+id/left_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/left_arrow"
android:layout_alignTop="@+id/imageView"
android:layout_toLeftOf="@+id/imageView"
android:layout_toStartOf="@+id/imageView" />
<ImageView
android:id="@+id/right_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/right_arrow"
android:layout_below="@+id/offer_image"
android:layout_toRightOf="@+id/imageView"
android:layout_toEndOf="@+id/imageView" />
final SwipeDeckAdapter adapter = new SwipeDeckAdapter(testData, this);
cardStack.setAdapter(adapter);
cardStack.setLeftImage(R.id.left_image);
cardStack.setRightImage(R.id.right_image);
Button btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cardStack.swipeTopCardLeft();
}
});
Button btn2 = (Button) findViewById(R.id.button2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cardStack.swipeTopCardRight();
}
});
Hardware Acceleration
In a future release this will be enabled by default but for now:
cardStack = (SwipeDeck) findViewById(R.id.swipe_deck);
cardStack.setHardwareAccelerationEnabled(true);
currently, this just enables rendering the cards to an offscreen buffer. It works well on every device I’ve tested but if you run into issues please let me know.
Download complete project source code from GitHub