diff --git a/README.md b/README.md index e74267f2d8..1c8b50c59d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Be sure to add the `@aar` suffix. ```groovy dependencies { - compile 'com.lorentzos.swipecards:library:X.X.X@aar' + implementation 'com.lorentzos.swipecards:library:X.X.X@aar' } ``` diff --git a/build.gradle b/build.gradle index 1d443d3a43..318d011d48 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,6 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' - - } } @@ -20,3 +18,14 @@ allprojects { jcenter() } } + +android { + buildToolsVersion '28.0.3' + compileSdkVersion 27 + + buildTypes { + release {} + debug {} + qa {} + } +} \ No newline at end of file diff --git a/example/build.gradle b/example/build.gradle index b10be86ed1..6458fd4c0e 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion Integer.parseInt(project.TARGET_SDK_VERSION) - buildToolsVersion "22.0.1" + buildToolsVersion "28.0.3" defaultConfig { applicationId "com.lorentzos.swipecards.example" @@ -20,7 +20,7 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile project(':library') - compile 'com.jakewharton:butterknife:5.1.2' + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation project(':library') + implementation 'com.jakewharton:butterknife:9.0.0-rc1' } diff --git a/library/build.gradle b/library/build.gradle index f294559252..f66cd6ac32 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -4,7 +4,7 @@ apply plugin: 'signing' android { compileSdkVersion Integer.parseInt(project.TARGET_SDK_VERSION) - buildToolsVersion "22.0.1" + buildToolsVersion '28.0.3' defaultConfig { minSdkVersion MIN_SDK_VERSION @@ -21,7 +21,7 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/library/src/main/java/com/lorentzos/flingswipe/FlingCardListener.java b/library/src/main/java/com/lorentzos/flingswipe/FlingCardListener.java index 5e15f10628..a45bf1e38e 100644 --- a/library/src/main/java/com/lorentzos/flingswipe/FlingCardListener.java +++ b/library/src/main/java/com/lorentzos/flingswipe/FlingCardListener.java @@ -72,107 +72,109 @@ public FlingCardListener(View frame, Object itemAtPosition, float rotation_degre public boolean onTouch(View view, MotionEvent event) { - - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: - - // from http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html - // Save the ID of this pointer - - mActivePointerId = event.getPointerId(0); - float x = 0; - float y = 0; - boolean success = false; - try { - x = event.getX(mActivePointerId); - y = event.getY(mActivePointerId); - success = true; - } catch (IllegalArgumentException e) { - Log.w(TAG, "Exception in onTouch(view, event) : " + mActivePointerId, e); - } - if (success) { - // Remember where we started - aDownTouchX = x; - aDownTouchY = y; - //to prevent an initial jump of the magnifier, aposX and aPosY must - //have the values from the magnifier frame - if (aPosX == 0) { - aPosX = frame.getX(); + if (!isAnimationRunning) { + switch (event.getAction() & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: + + // from http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html + // Save the ID of this pointer + + mActivePointerId = event.getPointerId(0); + float x = 0; + float y = 0; + boolean success = false; + try { + x = event.getX(mActivePointerId); + y = event.getY(mActivePointerId); + success = true; + } catch (IllegalArgumentException e) { + Log.w(TAG, "Exception in onTouch(view, event) : " + mActivePointerId, e); } - if (aPosY == 0) { - aPosY = frame.getY(); + if (success) { + // Remember where we started + aDownTouchX = x; + aDownTouchY = y; + //to prevent an initial jump of the magnifier, aposX and aPosY must + //have the values from the magnifier frame + if (aPosX == 0) { + aPosX = frame.getX(); + } + if (aPosY == 0) { + aPosY = frame.getY(); + } + + if (y < objectH / 2) { + touchPosition = TOUCH_ABOVE; + } else { + touchPosition = TOUCH_BELOW; + } } - if (y < objectH / 2) { - touchPosition = TOUCH_ABOVE; - } else { - touchPosition = TOUCH_BELOW; + view.getParent().requestDisallowInterceptTouchEvent(true); + break; + + case MotionEvent.ACTION_UP: + mActivePointerId = INVALID_POINTER_ID; + resetCardViewOnStack(); + view.getParent().requestDisallowInterceptTouchEvent(false); + break; + + case MotionEvent.ACTION_POINTER_DOWN: + break; + + case MotionEvent.ACTION_POINTER_UP: + // Extract the index of the pointer that left the touch sensor + final int pointerIndex = (event.getAction() & + MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + final int pointerId = event.getPointerId(pointerIndex); + if (pointerId == mActivePointerId) { + // This was our active pointer going up. Choose a new + // active pointer and adjust accordingly. + final int newPointerIndex = pointerIndex == 0 ? 1 : 0; + mActivePointerId = event.getPointerId(newPointerIndex); } - } + break; + case MotionEvent.ACTION_MOVE: - view.getParent().requestDisallowInterceptTouchEvent(true); - break; - - case MotionEvent.ACTION_UP: - mActivePointerId = INVALID_POINTER_ID; - resetCardViewOnStack(); - view.getParent().requestDisallowInterceptTouchEvent(false); - break; - - case MotionEvent.ACTION_POINTER_DOWN: - break; - - case MotionEvent.ACTION_POINTER_UP: - // Extract the index of the pointer that left the touch sensor - final int pointerIndex = (event.getAction() & - MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - final int pointerId = event.getPointerId(pointerIndex); - if (pointerId == mActivePointerId) { - // This was our active pointer going up. Choose a new - // active pointer and adjust accordingly. - final int newPointerIndex = pointerIndex == 0 ? 1 : 0; - mActivePointerId = event.getPointerId(newPointerIndex); - } - break; - case MotionEvent.ACTION_MOVE: + // Find the index of the active pointer and fetch its position + final int pointerIndexMove = event.findPointerIndex(mActivePointerId); + final float xMove = event.getX(pointerIndexMove); + final float yMove = event.getY(pointerIndexMove); - // Find the index of the active pointer and fetch its position - final int pointerIndexMove = event.findPointerIndex(mActivePointerId); - final float xMove = event.getX(pointerIndexMove); - final float yMove = event.getY(pointerIndexMove); + //from http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html + // Calculate the distance moved + final float dx = xMove - aDownTouchX; + final float dy = yMove - aDownTouchY; - //from http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html - // Calculate the distance moved - final float dx = xMove - aDownTouchX; - final float dy = yMove - aDownTouchY; + // Move the frame + aPosX += dx; + aPosY += dy; - // Move the frame - aPosX += dx; - aPosY += dy; + // calculate the rotation degrees + float distobjectX = aPosX - objectX; + float rotation = BASE_ROTATION_DEGREES * 2.f * distobjectX / parentWidth; + if (touchPosition == TOUCH_BELOW) { + rotation = -rotation; + } - // calculate the rotation degrees - float distobjectX = aPosX - objectX; - float rotation = BASE_ROTATION_DEGREES * 2.f * distobjectX / parentWidth; - if (touchPosition == TOUCH_BELOW) { - rotation = -rotation; + //in this area would be code for doing something with the view as the frame moves. + frame.setX(aPosX); + frame.setY(aPosY); + frame.setRotation(rotation); + mFlingListener.onScroll(getScrollProgressPercent()); + break; + + case MotionEvent.ACTION_CANCEL: { + mActivePointerId = INVALID_POINTER_ID; + view.getParent().requestDisallowInterceptTouchEvent(false); + break; } - - //in this area would be code for doing something with the view as the frame moves. - frame.setX(aPosX); - frame.setY(aPosY); - frame.setRotation(rotation); - mFlingListener.onScroll(getScrollProgressPercent()); - break; - - case MotionEvent.ACTION_CANCEL: { - mActivePointerId = INVALID_POINTER_ID; - view.getParent().requestDisallowInterceptTouchEvent(false); - break; } - } - return true; + return true; + } + return false; } private float getScrollProgressPercent() { @@ -187,11 +189,11 @@ private float getScrollProgressPercent() { } private boolean resetCardViewOnStack() { - if (movedBeyondLeftBorder()) { + if (movedBeyondLeftBorder() && mFlingListener.isLeftExitAvailable()) { // Left Swipe onSelected(true, getExitPoint(-objectW), 100); mFlingListener.onScroll(-1.0f); - } else if (movedBeyondRightBorder()) { + } else if (movedBeyondRightBorder() && mFlingListener.isRightExitAvailable()) { // Right Swipe onSelected(false, getExitPoint(parentWidth), 100); mFlingListener.onScroll(1.0f); @@ -270,7 +272,7 @@ public void onAnimationEnd(Animator animation) { * Starts a default left exit animation. */ public void selectLeft() { - if (!isAnimationRunning) + if (!isAnimationRunning && mFlingListener.isLeftExitAvailable()) onSelected(true, objectY, 200); } @@ -278,7 +280,7 @@ public void selectLeft() { * Starts a default right exit animation. */ public void selectRight() { - if (!isAnimationRunning) + if (!isAnimationRunning && mFlingListener.isRightExitAvailable()) onSelected(false, objectY, 200); } @@ -343,11 +345,9 @@ protected interface FlingListener { void onClick(Object dataObject); void onScroll(float scrollProgressPercent); - } - -} - - - + boolean isRightExitAvailable(); + boolean isLeftExitAvailable(); + } +} \ No newline at end of file diff --git a/library/src/main/java/com/lorentzos/flingswipe/SwipeFlingAdapterView.java b/library/src/main/java/com/lorentzos/flingswipe/SwipeFlingAdapterView.java index 1defa04420..1819d4820c 100644 --- a/library/src/main/java/com/lorentzos/flingswipe/SwipeFlingAdapterView.java +++ b/library/src/main/java/com/lorentzos/flingswipe/SwipeFlingAdapterView.java @@ -59,22 +59,22 @@ public SwipeFlingAdapterView(Context context, AttributeSet attrs, int defStyle) /** * A shortcut method to set both the listeners and the adapter. * - * @param context The activity context which extends onFlingListener, OnItemClickListener or both + * @param context The activity context which extends onFlingListener, OnItemClickListener or both * @param mAdapter The adapter you have to set. */ public void init(final Context context, Adapter mAdapter) { - if(context instanceof onFlingListener) { + if (context instanceof onFlingListener) { mFlingListener = (onFlingListener) context; - }else{ + } else { throw new RuntimeException("Activity does not implement SwipeFlingAdapterView.onFlingListener"); } - if(context instanceof OnItemClickListener){ + if (context instanceof OnItemClickListener) { mOnItemClickListener = (OnItemClickListener) context; } setAdapter(mAdapter); } - @Override + @Override public View getSelectedView() { return mActiveCard; } @@ -98,11 +98,11 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto mInLayout = true; final int adapterCount = mAdapter.getCount(); - if(adapterCount == 0) { + if (adapterCount == 0) { removeAllViewsInLayout(); - }else { + } else { View topCard = getChildAt(LAST_OBJECT_IN_STACK); - if(mActiveCard!=null && topCard!=null && topCard==mActiveCard) { + if (mActiveCard != null && topCard != null && topCard == mActiveCard) { if (this.flingCardListener.isTouching()) { PointF lastPoint = this.flingCardListener.getLastPoint(); if (this.mLastTouchPoint == null || !this.mLastTouchPoint.equals(lastPoint)) { @@ -111,7 +111,7 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto layoutChildren(1, adapterCount); } } - }else{ + } else { // Reset the UI and set top view listener removeAllViewsInLayout(); layoutChildren(0, adapterCount); @@ -120,13 +120,13 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto } mInLayout = false; - - if(adapterCount <= MIN_ADAPTER_STACK) mFlingListener.onAdapterAboutToEmpty(adapterCount); + + if (adapterCount <= MIN_ADAPTER_STACK) mFlingListener.onAdapterAboutToEmpty(adapterCount); } - private void layoutChildren(int startingIndex, int adapterCount){ - while (startingIndex < Math.min(adapterCount, MAX_VISIBLE) ) { + private void layoutChildren(int startingIndex, int adapterCount) { + while (startingIndex < Math.min(adapterCount, MAX_VISIBLE)) { View newUnderChild = mAdapter.getView(startingIndex, null, this); if (newUnderChild.getVisibility() != GONE) { makeAndAddView(newUnderChild); @@ -174,7 +174,7 @@ private void makeAndAddView(View child) { int childTop; switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { case Gravity.CENTER_HORIZONTAL: - childLeft = (getWidth() + getPaddingLeft() - getPaddingRight() - w) / 2 + + childLeft = (getWidth() + getPaddingLeft() - getPaddingRight() - w) / 2 + lp.leftMargin - lp.rightMargin; break; case Gravity.END: @@ -187,7 +187,7 @@ private void makeAndAddView(View child) { } switch (verticalGravity) { case Gravity.CENTER_VERTICAL: - childTop = (getHeight() + getPaddingTop() - getPaddingBottom() - h) / 2 + + childTop = (getHeight() + getPaddingTop() - getPaddingBottom() - h) / 2 + lp.topMargin - lp.bottomMargin; break; case Gravity.BOTTOM: @@ -203,66 +203,74 @@ private void makeAndAddView(View child) { } - - /** - * Set the top view and add the fling listener - */ + * Set the top view and add the fling listener + */ private void setTopView() { - if(getChildCount()>0){ + if (getChildCount() > 0) { mActiveCard = getChildAt(LAST_OBJECT_IN_STACK); - if(mActiveCard!=null) { + if (mActiveCard != null) { flingCardListener = new FlingCardListener(mActiveCard, mAdapter.getItem(0), ROTATION_DEGREES, new FlingCardListener.FlingListener() { - @Override - public void onCardExited() { - mActiveCard = null; - mFlingListener.removeFirstObjectInAdapter(); - } + @Override + public void onCardExited() { + mActiveCard = null; + mFlingListener.removeFirstObjectInAdapter(); + } + + @Override + public void leftExit(Object dataObject) { + mFlingListener.onLeftCardExit(dataObject); + } + + @Override + public void rightExit(Object dataObject) { + mFlingListener.onRightCardExit(dataObject); + } - @Override - public void leftExit(Object dataObject) { - mFlingListener.onLeftCardExit(dataObject); - } + @Override + public void onClick(Object dataObject) { + if (mOnItemClickListener != null) + mOnItemClickListener.onItemClicked(0, dataObject); - @Override - public void rightExit(Object dataObject) { - mFlingListener.onRightCardExit(dataObject); - } + } - @Override - public void onClick(Object dataObject) { - if(mOnItemClickListener!=null) - mOnItemClickListener.onItemClicked(0, dataObject); + @Override + public void onScroll(float scrollProgressPercent) { + mFlingListener.onScroll(scrollProgressPercent); + } - } + @Override + public boolean isLeftExitAvailable() { + return mFlingListener.isLeftCardExitAvailable(); + } - @Override - public void onScroll(float scrollProgressPercent) { - mFlingListener.onScroll(scrollProgressPercent); - } - }); + @Override + public boolean isRightExitAvailable() { + return mFlingListener.isRightCardExitAvailable(); + } + }); mActiveCard.setOnTouchListener(flingCardListener); } } } - public FlingCardListener getTopCardListener() throws NullPointerException{ - if(flingCardListener==null){ + public FlingCardListener getTopCardListener() throws NullPointerException { + if (flingCardListener == null) { throw new NullPointerException(); } return flingCardListener; } - public void setMaxVisible(int MAX_VISIBLE){ + public void setMaxVisible(int MAX_VISIBLE) { this.MAX_VISIBLE = MAX_VISIBLE; } - public void setMinStackInAdapter(int MIN_ADAPTER_STACK){ + public void setMinStackInAdapter(int MIN_ADAPTER_STACK) { this.MIN_ADAPTER_STACK = MIN_ADAPTER_STACK; } @@ -281,7 +289,7 @@ public void setAdapter(Adapter adapter) { mAdapter = adapter; - if (mAdapter != null && mDataSetObserver == null) { + if (mAdapter != null && mDataSetObserver == null) { mDataSetObserver = new AdapterDataSetObserver(); mAdapter.registerDataSetObserver(mDataSetObserver); } @@ -291,13 +299,11 @@ public void setFlingListener(onFlingListener onFlingListener) { this.mFlingListener = onFlingListener; } - public void setOnItemClickListener(OnItemClickListener onItemClickListener){ + public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.mOnItemClickListener = onItemClickListener; } - - @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new FrameLayout.LayoutParams(getContext(), attrs); @@ -324,11 +330,17 @@ public interface OnItemClickListener { public interface onFlingListener { void removeFirstObjectInAdapter(); + void onLeftCardExit(Object dataObject); + void onRightCardExit(Object dataObject); + void onAdapterAboutToEmpty(int itemsInAdapter); + void onScroll(float scrollProgressPercent); - } + boolean isRightCardExitAvailable(); -} + boolean isLeftCardExitAvailable(); + } +} \ No newline at end of file