Swipe-Deck


Source link: https://github.com/aaronbond/Swipe-Deck

Swipe-Deck

A Tinder style Swipeable deck view for Android

Note

I Have re written this project from the ground up as SwipeDeck2 and it is available here: https://github.com/aaronbond/SwipeDeck2

I initially hacked this together rather speedily beginning at a hackathon, as a result it wasn't really as maintainable and updateable as I would have liked. After getting almost daily emails and support requests for something I considered throwaway code I decided to re write and start again. So please if you're adventurous go and try out SwipeDeck2 and help me make it suitable for a wide range of use cases.

A Message To Developers

This project is still under considerable amount of development, as such i tend to tweak the API occasionally, if things change a little come and read the README or send me an issue. Please send me issues and pull requests if you need something fixed or have a feature you want and be sure to tell me if you find a bug!

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> 

I've included some modified layouts (SwipeFrameLayout, SwipeRelativeLayout etc) for ease of use, but you can use any layout you desire. However you may not get the desired outcome unless you set android:clipChildren="false" on your containing layout. If you choose not to do this cards will be clipped as they move outside their view boundary.

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

 
}

}
);
 

Deck XML Attributes

"max_visible" - (Integer) number of cards rendered in the deck  "rotation_degrees" - (Float) degree of tilt offset as the card moves left / right  "card_spacing" - (Dimension) amount to offset each card on the Y axis, 0dp will put cards directly atop each other (dp, px etc)  "render_above" - (Boolean) render the cards above other views in the layout  "render_below" - (Boolean) render the cards below other views in the layout  "opacity_end" - (Float) if using the left and right swipe image feature, range from 0 - 1,  this is the point where your swipe images reach full opacity, for example 0.33 would mean  full opacity when the card moves as far as 1/3 of the screen space left or right

Features

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

Programatically Swipe the top card left / right:


  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.

TODO

Lots of optimisation work Plenty of features left to add (let me know if you think of any)

Addendum

Feel free to contact me or log an issue if there's something broken or missing. I'd be happy to fix it up. This is currently very early work and you should fully expect some issues I have yet to spot. currently requires minSdkVersion 14, i haven't tested it but should easily support all the way back to sdk 12. If for some reason people want that let me know and i'll release a version.

Resources

Handling Android Permission Rationale Properly.

Android Instagram Connector: use Instagram API.

This application helps you to connect to instagram API i two simple steps.

Android library that adds methods isForeground / isBackground / isReturnedFromBackground.

The Sweetest way into saving and loading to SharedPreferences.

Android RxJava library for Social auth (Google, Facebook) and Smart Lock For Passwords.

AssetCopier copies assets to real files then optionally uses MediaScannerConnection to scan them for media. The end result is real files in the file system all ready for consumption. It's especially useful for providing an app with test data (images/videos) for UI testing.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes