diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..afbdab3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..ed0c9be --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +SwipeableCardStack \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..217af47 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..e206d70 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..c28baa3 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4129944 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + Android API 18 Platform + + + + + + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4f8866c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100644 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..def6a6a --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/CardStack/.gitignore b/CardStack/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/CardStack/.gitignore @@ -0,0 +1 @@ +/build diff --git a/CardStack/CardStack.iml b/CardStack/CardStack.iml new file mode 100644 index 0000000..63cc9aa --- /dev/null +++ b/CardStack/CardStack.iml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CardStack/build.gradle b/CardStack/build.gradle new file mode 100644 index 0000000..cca2489 --- /dev/null +++ b/CardStack/build.gradle @@ -0,0 +1,25 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 19 + buildToolsVersion '20.0.0' + + defaultConfig { + applicationId "com.wenchao.card_stack" + minSdkVersion 19 + targetSdkVersion 19 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + runProguard false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:20.0.+' +} diff --git a/CardStack/proguard-rules.pro b/CardStack/proguard-rules.pro new file mode 100644 index 0000000..bb65c6f --- /dev/null +++ b/CardStack/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/CardStack/src/androidTest/java/com/wenchao/card_stack/ApplicationTest.java b/CardStack/src/androidTest/java/com/wenchao/card_stack/ApplicationTest.java new file mode 100644 index 0000000..9860f85 --- /dev/null +++ b/CardStack/src/androidTest/java/com/wenchao/card_stack/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.wenchao.card_stack; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/CardStack/src/main/AndroidManifest.xml b/CardStack/src/main/AndroidManifest.xml new file mode 100644 index 0000000..aefe359 --- /dev/null +++ b/CardStack/src/main/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/CardStack/src/main/java/com/wenchao/animation/AnimatorListenerAdapter.java b/CardStack/src/main/java/com/wenchao/animation/AnimatorListenerAdapter.java new file mode 100644 index 0000000..55db3a8 --- /dev/null +++ b/CardStack/src/main/java/com/wenchao/animation/AnimatorListenerAdapter.java @@ -0,0 +1,27 @@ +package com.wenchao.animation; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; + +public abstract class AnimatorListenerAdapter implements AnimatorListener { + @Override + public void onAnimationCancel(Animator arg0) { + + } + + @Override + public void onAnimationEnd(Animator arg0) { + + } + + @Override + public void onAnimationRepeat(Animator arg0) { + + } + + @Override + public void onAnimationStart(Animator arg0) { + + } + +} diff --git a/CardStack/src/main/java/com/wenchao/animation/RelativeLayoutParamsEvaluator.java b/CardStack/src/main/java/com/wenchao/animation/RelativeLayoutParamsEvaluator.java new file mode 100644 index 0000000..b688e27 --- /dev/null +++ b/CardStack/src/main/java/com/wenchao/animation/RelativeLayoutParamsEvaluator.java @@ -0,0 +1,21 @@ +package com.wenchao.animation; + +import android.animation.TypeEvaluator; +import android.widget.RelativeLayout.LayoutParams + ; + +public class RelativeLayoutParamsEvaluator implements TypeEvaluator { + + @Override + public LayoutParams evaluate(float fraction, LayoutParams start, + LayoutParams end) { + + LayoutParams result = new LayoutParams(start); + result.leftMargin += ((end.leftMargin-start.leftMargin)*fraction); + result.rightMargin += ((end.rightMargin-start.rightMargin)*fraction); + result.topMargin += ((end.topMargin-start.topMargin)*fraction); + result.bottomMargin += ((end.bottomMargin-start.bottomMargin)*fraction); + return result; + } + +} diff --git a/CardStack/src/main/java/com/wenchao/cardstack/CardAnimator.java b/CardStack/src/main/java/com/wenchao/cardstack/CardAnimator.java new file mode 100644 index 0000000..d3e9105 --- /dev/null +++ b/CardStack/src/main/java/com/wenchao/cardstack/CardAnimator.java @@ -0,0 +1,260 @@ +package com.wenchao.cardstack; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Random; + +import com.wenchao.animation.RelativeLayoutParamsEvaluator; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ValueAnimator; +import android.graphics.Color; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.RelativeLayout; +import android.widget.RelativeLayout.LayoutParams; + +public class CardAnimator{ + private static final String DEBUG_TAG = "CardAnimator"; + private static final int REMOTE_DISTANCE = 1000; + public ArrayList mCardCollection; + private float mRotation; + private HashMap mLayoutsMap; + private RelativeLayout.LayoutParams[] mRemoteLayouts = new RelativeLayout.LayoutParams[4]; + private RelativeLayout.LayoutParams baseLayout; + private int mStackMargin=20; + + public CardAnimator(ArrayList viewCollection){ + mCardCollection = viewCollection; + setup(); + + } + private void setup(){ + mLayoutsMap = new HashMap(); + + for(View v : mCardCollection){ + //setup basic layout + RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams(); + params.addRule(RelativeLayout.ALIGN_PARENT_TOP); + params.width = LayoutParams.MATCH_PARENT; + params.height = LayoutParams.MATCH_PARENT; + + Random rnd = new Random(); + int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)); + v.setBackgroundColor(color); + + v.setLayoutParams(params); + } + + baseLayout = (RelativeLayout.LayoutParams)mCardCollection.get(0).getLayoutParams(); + baseLayout = new RelativeLayout.LayoutParams(baseLayout); + + initLayout(); + + for (View v : mCardCollection){ + RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams(); + RelativeLayout.LayoutParams paramsCopy = new RelativeLayout.LayoutParams(params); + mLayoutsMap.put(v, paramsCopy); + } + + setupRemotes(); + + } + + public void initLayout(){ + int size = mCardCollection.size(); + for(View v : mCardCollection){ + int index = mCardCollection.indexOf(v); + if(index!=0){ + index-=1; + } + LayoutParams params = new LayoutParams(baseLayout); + v.setLayoutParams(params); + + CardUtils.scale(v, -(size - index - 1) * 5); + CardUtils.move(v, index * mStackMargin, 0); + v.setRotation(0); + } + } + + private void setupRemotes(){ + View topView = getTopView(); + mRemoteLayouts[0] = CardUtils.getMoveParams(topView, REMOTE_DISTANCE, -REMOTE_DISTANCE); + mRemoteLayouts[1] = CardUtils.getMoveParams(topView, REMOTE_DISTANCE, REMOTE_DISTANCE); + mRemoteLayouts[2] = CardUtils.getMoveParams(topView, -REMOTE_DISTANCE, -REMOTE_DISTANCE); + mRemoteLayouts[3] = CardUtils.getMoveParams(topView, -REMOTE_DISTANCE, REMOTE_DISTANCE); + + } + + private View getTopView(){ + return mCardCollection.get(mCardCollection.size()-1); + } + + private void moveToBack(View child) + { + final ViewGroup parent = (ViewGroup)child.getParent(); + if (null != parent) { + parent.removeView(child); + parent.addView(child, 0); + } + } + + private void reorder(){ + View temp = getTopView(); + //RelativeLayout.LayoutParams tempLp = mLayoutsMap.get(mCardCollection.get(0)); + //mLayoutsMap.put(temp,tempLp); + moveToBack(temp); + + for(int i=(mCardCollection.size()-1); i>0; i--){ + //View next = mCardCollection.get(i); + //RelativeLayout.LayoutParams lp = mLayoutsMap.get(next); + //mLayoutsMap.remove(next); + View current = mCardCollection.get(i-1); + //current replace next + mCardCollection.set(i,current); + //mLayoutsMap.put(current,lp); + + } + mCardCollection.set(0,temp); + + temp = getTopView(); + + } + + public void discard(int direction,final AnimatorListener al){ + AnimatorSet as = new AnimatorSet(); + ArrayList aCollection = new ArrayList(); + + + final View topView = getTopView(); + RelativeLayout.LayoutParams topParams = (RelativeLayout.LayoutParams) topView.getLayoutParams(); + RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(topParams); + ValueAnimator discardAnim = ValueAnimator.ofObject(new RelativeLayoutParamsEvaluator(),layout, mRemoteLayouts[direction]); + + discardAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator value) { + topView.setLayoutParams((LayoutParams)value.getAnimatedValue()); + } + }); + + discardAnim.setDuration(250); + aCollection.add(discardAnim); + + for(int i = 0; i< mCardCollection.size();i++){ + final View v = mCardCollection.get(i); + + if(v==topView) continue; + final View nv = mCardCollection.get(i+1); + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams(); + RelativeLayout.LayoutParams endLayout = new RelativeLayout.LayoutParams(layoutParams); + ValueAnimator layoutAnim = ValueAnimator.ofObject(new RelativeLayoutParamsEvaluator(),endLayout,mLayoutsMap.get(nv)); + layoutAnim.setDuration(250); + layoutAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator value) { + v.setLayoutParams((LayoutParams)value.getAnimatedValue()); + } + }); + aCollection.add(layoutAnim); + } + + as.addListener(new AnimatorListenerAdapter(){ + + + @Override + public void onAnimationEnd(Animator animation) { + reorder(); + if(al != null){ + al.onAnimationEnd(animation); + } + mLayoutsMap = new HashMap(); + for (View v : mCardCollection){ + RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams(); + RelativeLayout.LayoutParams paramsCopy = new RelativeLayout.LayoutParams(params); + mLayoutsMap.put(v, paramsCopy); + } + + } + + }); + + + as.playTogether(aCollection); + as.start(); + + + } + + public void reverse(MotionEvent e1, MotionEvent e2){ + final View topView = getTopView(); + ValueAnimator rotationAnim = ValueAnimator.ofFloat(mRotation, 0f); + rotationAnim.setDuration(250); + rotationAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator v) { + topView.setRotation(((Float) (v.getAnimatedValue())).floatValue()); + } + }); + + rotationAnim.start(); + + for(final View v : mCardCollection){ + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams(); + RelativeLayout.LayoutParams endLayout = new RelativeLayout.LayoutParams(layoutParams); + ValueAnimator layoutAnim = ValueAnimator.ofObject(new RelativeLayoutParamsEvaluator(),endLayout,mLayoutsMap.get(v)); + layoutAnim.setDuration(250); + layoutAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator value) { + v.setLayoutParams((LayoutParams)value.getAnimatedValue()); + } + }); + layoutAnim.start(); + } + + } + + public void drag(MotionEvent e1, MotionEvent e2, float distanceX, + float distanceY){ + + View topView = getTopView(); + + float rotation_coefficient = 20f; + + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) topView.getLayoutParams(); + RelativeLayout.LayoutParams topViewLayouts = mLayoutsMap.get(topView); + int x_diff = (int)((e2.getRawX()-e1.getRawX())); + int y_diff = (int)((e2.getRawY()-e1.getRawY())); + + layoutParams.leftMargin = topViewLayouts.leftMargin+ x_diff; + layoutParams.rightMargin = topViewLayouts.rightMargin - x_diff; + layoutParams.topMargin = topViewLayouts.topMargin + y_diff; + layoutParams.bottomMargin = topViewLayouts.bottomMargin - y_diff; + + mRotation = (x_diff/rotation_coefficient); + topView.setRotation(mRotation); + topView.setLayoutParams(layoutParams); + + //animate secondary views. + for(View v : mCardCollection){ + int index = mCardCollection.indexOf(v); + if(v!=getTopView() && index != 0){ + LayoutParams l = CardUtils.scaleFrom(v, mLayoutsMap.get(v), (int) (Math.abs(x_diff) * 0.05)); + CardUtils.moveFrom(v, l, 0, (int) (Math.abs(x_diff) * 0.1)); + } + } + } + + public void setStackMargin(int margin) { + mStackMargin = margin; + initLayout(); + } + + + +} diff --git a/CardStack/src/main/java/com/wenchao/cardstack/CardStack.java b/CardStack/src/main/java/com/wenchao/cardstack/CardStack.java new file mode 100644 index 0000000..34a605c --- /dev/null +++ b/CardStack/src/main/java/com/wenchao/cardstack/CardStack.java @@ -0,0 +1,269 @@ +package com.wenchao.cardstack; + +import java.util.ArrayList; +import java.util.Queue; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.FrameLayout; +import android.widget.RelativeLayout; +import android.database.DataSetObserver; + + +public class CardStack extends RelativeLayout { + private int mIndex = 0; + private int mNumVisible = 4; + private ArrayAdapter mAdapter; + private OnTouchListener mOnTouchListener; + private CardAnimator mCardAnimator; + //private Queue mIdleStack = new Queue; + + + + private CardEventListener mEventListener = new DefaultStackEventListener(300); + private int mContentResource = 0; + + + public interface CardEventListener{ + //section + // 0 | 1 + //-------- + // 2 | 3 + // swipe distance, most likely be used with height and width of a view ; + + public boolean swipeEnd(int section,float distance); + public boolean swipeStart(int section,float distance); + public boolean swipeContinue(int section, float distanceX,float distanceY ); + public void discarded(int mIndex, int direction); + public void topCardTapped(); + } + + public void discardTop(final int direction){ + mCardAnimator.discard(direction, new AnimatorListenerAdapter(){ + @Override + public void onAnimationEnd(Animator arg0) { + mCardAnimator.initLayout(); + mIndex++; + mEventListener.discarded(mIndex,direction); + + //mIndex = mIndex%mAdapter.getCount(); + loadLast(); + + viewCollection.get(0).setOnTouchListener(null); + viewCollection.get(viewCollection.size()-1) + .setOnTouchListener(mOnTouchListener); + } + }); + } + + public int getCurrIndex(){ + //sync? + return mIndex; + } + + //only necessary when I need the attrs from xml, this will be used when inflating layout + public CardStack(Context context, AttributeSet attrs) { + super(context, attrs); + + //String sMyValue = attrs.getAttributeValue( "http://schemas.android.com/apk/res/android", "padding" ); + //get attrs assign minVisiableNum + for(int i = 0; i viewCollection = new ArrayList(); + public CardStack(Context context) { + super(context); + } + + public void setAdapter(final ArrayAdapter adapter){ + if(mAdapter != null){ + mAdapter.unregisterDataSetObserver(mOb); + } + mAdapter = adapter; + adapter.registerDataSetObserver(mOb); + + loadData(); + } + + private void loadData(){ + for(int i=mNumVisible-1 ; i>=0 ; i--) { + ViewGroup parent = (ViewGroup) viewCollection.get(i); + int index = (mIndex + mNumVisible - 1) - i; + if (index > mAdapter.getCount() - 1) { + parent.setVisibility(View.GONE); + }else{ + View child = mAdapter.getView(index, getContentView(), this); + parent.addView(child); + parent.setVisibility(View.VISIBLE); + } + } + } + + private View getContentView(){ + View contentView = null; + if(mContentResource != 0) { + LayoutInflater lf = LayoutInflater.from(getContext()); + contentView = lf.inflate(mContentResource,null); + } + return contentView; + + } + + private void loadLast(){ + ViewGroup parent = (ViewGroup)viewCollection.get(0); + + int lastIndex = (mNumVisible - 1)+ mIndex; + if(lastIndex > mAdapter.getCount() -1 ){ + parent.setVisibility(View.GONE); + return; + } + + View child = mAdapter.getView( lastIndex, getContentView(), parent); + parent.removeAllViews(); + parent.addView(child); + } + + public int getStackSize() { + return mNumVisible; + } +} diff --git a/CardStack/src/main/java/com/wenchao/cardstack/CardUtils.java b/CardStack/src/main/java/com/wenchao/cardstack/CardUtils.java new file mode 100644 index 0000000..47ffa4e --- /dev/null +++ b/CardStack/src/main/java/com/wenchao/cardstack/CardUtils.java @@ -0,0 +1,102 @@ +package com.wenchao.cardstack; + +import android.util.Log; +import android.view.View; +import android.widget.RelativeLayout; +import android.widget.RelativeLayout.LayoutParams; + +public class CardUtils { + final static int DIRECTION_TOP_LEFT = 0; + final static int DIRECTION_TOP_RIGHT = 1; + final static int DIRECTION_BOTTOM_LEFT = 2; + final static int DIRECTION_BOTTOM_RIGHT = 3; + + public static void scale(View v, int pixel){ + RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)v.getLayoutParams(); + params.leftMargin -= pixel; + params.rightMargin -= pixel; + params.topMargin -= pixel; + params.bottomMargin -= pixel; + v.setLayoutParams(params); + } + + public static LayoutParams getMoveParams(View v, int upDown,int leftRight){ + RelativeLayout.LayoutParams original = (RelativeLayout.LayoutParams)v.getLayoutParams(); + //RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(original); + RelativeLayout.LayoutParams params = cloneParams(original); + params.leftMargin += leftRight; + params.rightMargin -= leftRight; + params.topMargin -= upDown; + params.bottomMargin += upDown; + return params; + } + + public static void move(View v, int upDown,int leftRight){ + RelativeLayout.LayoutParams params = getMoveParams(v,upDown,leftRight); + v.setLayoutParams(params); + } + + public static LayoutParams scaleFrom(View v, LayoutParams params, int pixel) { + Log.d("pixel", "onScroll: " + pixel); + params = cloneParams(params); + params.leftMargin -= pixel; + params.rightMargin -= pixel; + params.topMargin -= pixel; + params.bottomMargin -= pixel; + Log.d("pixel", "onScroll: " + pixel); + v.setLayoutParams(params); + + return params; + } + + public static LayoutParams moveFrom(View v, LayoutParams params, int leftRight, int upDown) { + params = cloneParams(params); + params.leftMargin += leftRight; + params.rightMargin -= leftRight; + params.topMargin -= upDown; + params.bottomMargin += upDown; + v.setLayoutParams(params); + + return params; + } + + //a copy method for RelativeLayout.LayoutParams for backward compartibility + public static RelativeLayout.LayoutParams cloneParams(RelativeLayout.LayoutParams params){ + RelativeLayout.LayoutParams copy = new RelativeLayout.LayoutParams(params.width,params.height); + copy.leftMargin = params.leftMargin; + copy.topMargin = params.topMargin; + copy.rightMargin = params.rightMargin; + copy.bottomMargin = params.bottomMargin; + int[] rules = params.getRules(); + for (int i = 0 ; i< rules.length; i++ ){ + copy.addRule(i,rules[i]); + } + copy.setMarginStart(params.getMarginStart()); + copy.setMarginEnd(params.getMarginEnd()); + + return copy; + } + + public static float distance(float x1, float y1, float x2, float y2) { + + return (float) Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); + } + + public static int direction(float x1, float y1, float x2, float y2) { + if(x2>x1){//RIGHT + if(y2>y1){//BOTTOM + return DIRECTION_BOTTOM_RIGHT; + }else{//TOP + return DIRECTION_TOP_RIGHT; + } + }else{//LEFT + if(y2>y1){//BOTTOM + return DIRECTION_BOTTOM_LEFT; + }else{//TOP + return DIRECTION_TOP_LEFT; + } + } + } + + +} diff --git a/CardStack/src/main/java/com/wenchao/cardstack/DefaultStackEventListener.java b/CardStack/src/main/java/com/wenchao/cardstack/DefaultStackEventListener.java new file mode 100644 index 0000000..add9fa2 --- /dev/null +++ b/CardStack/src/main/java/com/wenchao/cardstack/DefaultStackEventListener.java @@ -0,0 +1,42 @@ +package com.wenchao.cardstack; + +public class DefaultStackEventListener implements CardStack.CardEventListener { + + private float mThreshold; + + public DefaultStackEventListener(int i) { + mThreshold = i; + } + + @Override + public boolean swipeEnd(int section, float distance) { + if(distance > mThreshold){ + return true; + }else{ + return false; + } + } + + @Override + public boolean swipeStart(int section, float distance) { + + return false; + } + + @Override + public boolean swipeContinue(int section, float distanceX, float distanceY) { + return false; + } + + @Override + public void discarded(int mIndex,int direction) { + + } + + @Override + public void topCardTapped() { + + } + + +} diff --git a/CardStack/src/main/java/com/wenchao/cardstack/DragGestureDetector.java b/CardStack/src/main/java/com/wenchao/cardstack/DragGestureDetector.java new file mode 100644 index 0000000..4fa9d63 --- /dev/null +++ b/CardStack/src/main/java/com/wenchao/cardstack/DragGestureDetector.java @@ -0,0 +1,74 @@ +package com.wenchao.cardstack; + +import android.content.Context; +import android.support.v4.view.GestureDetectorCompat; +import android.support.v4.view.MotionEventCompat; +import android.util.Log; +import android.view.GestureDetector; +import android.view.MotionEvent; + + +//detect both tap and drag +public class DragGestureDetector { + public static String DEBUG_TAG = "DragGestureDetector"; + GestureDetectorCompat mGestrueDetector; + DragListener mListener; + private boolean mStarted = false; + private MotionEvent mOriginalEvent; + public static interface DragListener { + public boolean onDragStart(MotionEvent e1, MotionEvent e2, float distanceX, + float distanceY); + public boolean onDragContinue(MotionEvent e1, MotionEvent e2, float distanceX, + float distanceY); + public boolean onDragEnd(MotionEvent e1, MotionEvent e2); + + public boolean onTapUp(); + } + + public DragGestureDetector(Context context, DragListener myDragListener){ + mGestrueDetector = new GestureDetectorCompat(context,new MyGestureListener()); + mListener = myDragListener; + } + + public void onTouchEvent(MotionEvent event){ + mGestrueDetector.onTouchEvent(event); + int action = MotionEventCompat.getActionMasked(event); + switch(action) { + case (MotionEvent.ACTION_UP) : + Log.d(DEBUG_TAG,"Action was UP"); + if(mStarted) { + mListener.onDragEnd(mOriginalEvent, event); + } + mStarted = false; + case (MotionEvent.ACTION_DOWN) : + //need to set this, quick tap will not generate drap event, so the + //originalEvent may be null for case action_up + //which lead to null pointer + mOriginalEvent = event; + } + } + + class MyGestureListener extends GestureDetector.SimpleOnGestureListener { + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, + float distanceY) { + if(mListener == null) return true; + if( mStarted == false){ + mListener.onDragStart(e1,e2,distanceX,distanceY); + mStarted = true; + } + else{ + mListener.onDragContinue(e1,e2,distanceX,distanceY); + } + mOriginalEvent = e1; + return true; + } + + @Override + public boolean onSingleTapUp(MotionEvent e) { + + return mListener.onTapUp(); + } + } + + +} diff --git a/CardStack/src/main/res/drawable-hdpi/ic_launcher.png b/CardStack/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/CardStack/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/CardStack/src/main/res/drawable-mdpi/ic_launcher.png b/CardStack/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/CardStack/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/CardStack/src/main/res/drawable-xhdpi/ic_launcher.png b/CardStack/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/CardStack/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/CardStack/src/main/res/drawable-xxhdpi/ic_launcher.png b/CardStack/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..4df1894 Binary files /dev/null and b/CardStack/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/CardStack/src/main/res/values/attrs.xml b/CardStack/src/main/res/values/attrs.xml new file mode 100644 index 0000000..6003f87 --- /dev/null +++ b/CardStack/src/main/res/values/attrs.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/CardStack/src/main/res/values/strings.xml b/CardStack/src/main/res/values/strings.xml new file mode 100644 index 0000000..f235cc9 --- /dev/null +++ b/CardStack/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + SwipeableCardStack + diff --git a/SwipeableCardStack.iml b/SwipeableCardStack.iml new file mode 100644 index 0000000..0bb6048 --- /dev/null +++ b/SwipeableCardStack.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/app.iml b/app/app.iml new file mode 100644 index 0000000..96ccbda --- /dev/null +++ b/app/app.iml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..41024c2 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 19 + buildToolsVersion '20.0.0' + + defaultConfig { + applicationId "wxj.swipeablecardstack" + minSdkVersion 19 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + runProguard false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile project(':CardStack') + compile 'com.android.support:appcompat-v7:20.0.+' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..bb65c6f --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/wxj/swipeablecardstack/ApplicationTest.java b/app/src/androidTest/java/wxj/swipeablecardstack/ApplicationTest.java new file mode 100644 index 0000000..51e7bec --- /dev/null +++ b/app/src/androidTest/java/wxj/swipeablecardstack/ApplicationTest.java @@ -0,0 +1,13 @@ +package wxj.swipeablecardstack; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..dbc78ff --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/java/wxj/swipeablecardstack/CardsDataAdapter.java b/app/src/main/java/wxj/swipeablecardstack/CardsDataAdapter.java new file mode 100644 index 0000000..be6b9cb --- /dev/null +++ b/app/src/main/java/wxj/swipeablecardstack/CardsDataAdapter.java @@ -0,0 +1,25 @@ +package wxj.swipeablecardstack; + +import android.content.Context; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +public class CardsDataAdapter extends ArrayAdapter { + + public CardsDataAdapter(Context context, int resource) { + super(context, resource); + } + + @Override + public View getView(int position, final View contentView, ViewGroup parent){ + TextView v = (TextView)(contentView.findViewById(R.id.content)); + v.setText(getItem(position)); + return contentView; + } + +} + diff --git a/app/src/main/java/wxj/swipeablecardstack/MyActivity.java b/app/src/main/java/wxj/swipeablecardstack/MyActivity.java new file mode 100644 index 0000000..d096102 --- /dev/null +++ b/app/src/main/java/wxj/swipeablecardstack/MyActivity.java @@ -0,0 +1,52 @@ +package wxj.swipeablecardstack; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +import com.wenchao.cardstack.CardStack; + + +public class MyActivity extends Activity { + private CardStack mCardStack; + private CardsDataAdapter mCardAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_my); + + mCardStack = (CardStack)findViewById(R.id.container); + //wrong move it to adapter!!! + mCardStack.setContentResource(R.layout.card_content); + mCardStack.setStackMargin(20); + mCardAdapter = new CardsDataAdapter(getApplicationContext(),0); + mCardAdapter.add("test1"); + mCardAdapter.add("test2"); + mCardAdapter.add("test3"); + mCardAdapter.add("test4"); + mCardAdapter.add("test5"); + mCardStack.setAdapter(mCardAdapter); + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.my, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + if (id == R.id.action_settings) { + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..4df1894 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/layout/activity_my.xml b/app/src/main/res/layout/activity_my.xml new file mode 100644 index 0000000..320a1da --- /dev/null +++ b/app/src/main/res/layout/activity_my.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/app/src/main/res/layout/card_content.xml b/app/src/main/res/layout/card_content.xml new file mode 100644 index 0000000..1f2985c --- /dev/null +++ b/app/src/main/res/layout/card_content.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/my.xml b/app/src/main/res/menu/my.xml new file mode 100644 index 0000000..bea58cc --- /dev/null +++ b/app/src/main/res/menu/my.xml @@ -0,0 +1,8 @@ + + + diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..63fc816 --- /dev/null +++ b/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..47c8224 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..4eae12b --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + SwipeableCardStack + Hello world! + Settings + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..ff6c9d2 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..9b8abe4 --- /dev/null +++ b/build.gradle @@ -0,0 +1,19 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:0.12.2' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..5d08ba7 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Settings specified in this file will override any Gradle settings +# configured through the IDE. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..8c0fb64 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..1e61d1f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..aec9973 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..90fe847 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app', ':CardStack'